11from __future__ import annotations
22
3- from typing import Union
3+ from typing import List , Literal , Union
44
55from typing_extensions import TypedDict
66
7+ ErrorCode = Literal [
8+ "unexpected_failure" ,
9+ "validation_failed" ,
10+ "bad_json" ,
11+ "email_exists" ,
12+ "phone_exists" ,
13+ "bad_jwt" ,
14+ "not_admin" ,
15+ "no_authorization" ,
16+ "user_not_found" ,
17+ "session_not_found" ,
18+ "flow_state_not_found" ,
19+ "flow_state_expired" ,
20+ "signup_disabled" ,
21+ "user_banned" ,
22+ "provider_email_needs_verification" ,
23+ "invite_not_found" ,
24+ "bad_oauth_state" ,
25+ "bad_oauth_callback" ,
26+ "oauth_provider_not_supported" ,
27+ "unexpected_audience" ,
28+ "single_identity_not_deletable" ,
29+ "email_conflict_identity_not_deletable" ,
30+ "identity_already_exists" ,
31+ "email_provider_disabled" ,
32+ "phone_provider_disabled" ,
33+ "too_many_enrolled_mfa_factors" ,
34+ "mfa_factor_name_conflict" ,
35+ "mfa_factor_not_found" ,
36+ "mfa_ip_address_mismatch" ,
37+ "mfa_challenge_expired" ,
38+ "mfa_verification_failed" ,
39+ "mfa_verification_rejected" ,
40+ "insufficient_aal" ,
41+ "captcha_failed" ,
42+ "saml_provider_disabled" ,
43+ "manual_linking_disabled" ,
44+ "sms_send_failed" ,
45+ "email_not_confirmed" ,
46+ "phone_not_confirmed" ,
47+ "reauth_nonce_missing" ,
48+ "saml_relay_state_not_found" ,
49+ "saml_relay_state_expired" ,
50+ "saml_idp_not_found" ,
51+ "saml_assertion_no_user_id" ,
52+ "saml_assertion_no_email" ,
53+ "user_already_exists" ,
54+ "sso_provider_not_found" ,
55+ "saml_metadata_fetch_failed" ,
56+ "saml_idp_already_exists" ,
57+ "sso_domain_already_exists" ,
58+ "saml_entity_id_mismatch" ,
59+ "conflict" ,
60+ "provider_disabled" ,
61+ "user_sso_managed" ,
62+ "reauthentication_needed" ,
63+ "same_password" ,
64+ "reauthentication_not_valid" ,
65+ "otp_expired" ,
66+ "otp_disabled" ,
67+ "identity_not_found" ,
68+ "weak_password" ,
69+ "over_request_rate_limit" ,
70+ "over_email_send_rate_limit" ,
71+ "over_sms_send_rate_limit" ,
72+ "bad_code_verifier" ,
73+ ]
74+
775
876class AuthError (Exception ):
9- def __init__ (self , message : str ) -> None :
77+ def __init__ (self , message : str , code : ErrorCode ) -> None :
1078 Exception .__init__ (self , message )
1179 self .message = message
1280 self .name = "AuthError"
81+ self .code = code
1382
1483
1584class AuthApiErrorDict (TypedDict ):
1685 name : str
1786 message : str
1887 status : int
88+ code : ErrorCode
1989
2090
2191class AuthApiError (AuthError ):
22- def __init__ (self , message : str , status : int ) -> None :
23- AuthError .__init__ (self , message )
92+ def __init__ (self , message : str , status : int , code : ErrorCode ) -> None :
93+ AuthError .__init__ (self , message , code )
2494 self .name = "AuthApiError"
2595 self .status = status
96+ self .code = code
2697
2798 def to_dict (self ) -> AuthApiErrorDict :
2899 return {
29100 "name" : self .name ,
30101 "message" : self .message ,
31102 "status" : self .status ,
103+ "code" : self .code ,
32104 }
33105
34106
35107class AuthUnknownError (AuthError ):
36108 def __init__ (self , message : str , original_error : Exception ) -> None :
37- AuthError .__init__ (self , message )
109+ AuthError .__init__ (self , message , None )
38110 self .name = "AuthUnknownError"
39111 self .original_error = original_error
40112
41113
42114class CustomAuthError (AuthError ):
43- def __init__ (self , message : str , name : str , status : int ) -> None :
44- AuthError .__init__ (self , message )
115+ def __init__ (self , message : str , name : str , status : int , code : ErrorCode ) -> None :
116+ AuthError .__init__ (self , message , code )
45117 self .name = name
46118 self .status = status
47119
@@ -60,6 +132,7 @@ def __init__(self) -> None:
60132 "Auth session missing!" ,
61133 "AuthSessionMissingError" ,
62134 400 ,
135+ None ,
63136 )
64137
65138
@@ -70,6 +143,7 @@ def __init__(self, message: str) -> None:
70143 message ,
71144 "AuthInvalidCredentialsError" ,
72145 400 ,
146+ None ,
73147 )
74148
75149
@@ -93,6 +167,7 @@ def __init__(
93167 message ,
94168 "AuthImplicitGrantRedirectError" ,
95169 500 ,
170+ None ,
96171 )
97172 self .details = details
98173
@@ -112,4 +187,25 @@ def __init__(self, message: str, status: int) -> None:
112187 message ,
113188 "AuthRetryableError" ,
114189 status ,
190+ None ,
115191 )
192+
193+
194+ class AuthWeakPasswordError (CustomAuthError ):
195+ def __init__ (self , message : str , status : int , reasons : List [str ]) -> None :
196+ CustomAuthError .__init__ (
197+ self ,
198+ message ,
199+ "AuthWeakPasswordError" ,
200+ status ,
201+ "weak_password" ,
202+ )
203+ self .reasons = reasons
204+
205+ def to_dict (self ) -> AuthApiErrorDict :
206+ return {
207+ "name" : self .name ,
208+ "message" : self .message ,
209+ "status" : self .status ,
210+ "reasons" : self .reasons ,
211+ }
0 commit comments