Skip to content

Commit 19b09ca

Browse files
authored
feat!: remove deprecated PassageError ctor (#131)
1 parent 236c989 commit 19b09ca

File tree

4 files changed

+34
-65
lines changed

4 files changed

+34
-65
lines changed

Diff for: passageidentity/auth.py

+21-14
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,27 @@ def validate_jwt(self, jwt: str) -> str:
4040
msg = "jwt is required."
4141
raise ValueError(msg)
4242

43-
try:
44-
kid = pyjwt.get_unverified_header(jwt)["kid"]
45-
public_key = self.jwks.get_signing_key(kid)
46-
claims = pyjwt.decode(
47-
jwt,
48-
public_key,
49-
audience=self.app_id,
50-
algorithms=["RS256"],
51-
)
52-
53-
return claims["sub"]
54-
except Exception as e:
55-
msg = f"JWT is not valid: {e}"
56-
raise PassageError(msg) from e
43+
header = pyjwt.get_unverified_header(jwt)
44+
kid = header.get("kid")
45+
46+
if kid is None:
47+
msg = "kid is missing in the JWT header."
48+
raise ValueError(msg)
49+
50+
public_key = self.jwks.get_signing_key(kid)
51+
claims = pyjwt.decode(
52+
jwt,
53+
public_key,
54+
audience=self.app_id,
55+
algorithms=["RS256"],
56+
)
57+
58+
sub = claims.get("sub")
59+
if sub is None:
60+
msg = "sub is missing in the JWT claims."
61+
raise ValueError(msg)
62+
63+
return sub
5764

5865
def create_magic_link(self, args: MagicLinkArgs, options: MagicLinkOptions | None = None) -> MagicLink:
5966
"""Create a Magic Link for your app."""

Diff for: passageidentity/errors.py

+9-25
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,16 @@
44

55
from typing import TYPE_CHECKING
66

7-
import typing_extensions
8-
97
if TYPE_CHECKING:
108
from passageidentity.openapi_client.exceptions import ApiException
119

1210

1311
class PassageError(Exception):
1412
"""Error class for handling Passage errors."""
1513

16-
@typing_extensions.deprecated(
17-
"This should only be constructed by the Passage SDK. Use this type just for type checking.",
18-
)
19-
def __init__(
20-
self,
21-
message: str,
22-
status_code: int | None = None,
23-
status_text: str | None = None,
24-
body: dict | None = None,
25-
error_code: str | None = None,
26-
) -> None:
27-
"""Initialize the error with a message, status code, status text, and optional body."""
28-
self.message = message
29-
self.status_code = status_code
30-
self.status_text = status_text
31-
32-
self.error_code = error_code
33-
self.error = None
34-
35-
if body is not None:
36-
self.error = body["error"]
37-
self.error_code = body["code"]
14+
message: str
15+
status_code: int | None
16+
error_code: str | None
3817

3918
def __str__(self) -> str:
4019
"""Return the error message."""
@@ -52,4 +31,9 @@ def from_response_error(cls, response_error: ApiException, message: str | None =
5231
error_code = None
5332
msg = str(response_error.body)
5433

55-
return cls(message=msg, status_code=response_error.status, error_code=error_code)
34+
psg_error = cls()
35+
psg_error.message = msg
36+
psg_error.status_code = response_error.status
37+
psg_error.error_code = error_code
38+
39+
return psg_error

Diff for: passageidentity/user.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from passageidentity.errors import PassageError
88
from passageidentity.openapi_client.exceptions import ApiException
9+
from passageidentity.openapi_client.models.model404_error import Model404Error
910

1011
from .openapi_client.api import (
1112
TokensApi,
@@ -63,8 +64,9 @@ def get_by_identifier(self, identifier: str) -> PassageUser:
6364
raise PassageError.from_response_error(e, msg) from e
6465

6566
if len(users) == 0:
66-
msg = "User not found."
67-
raise PassageError(msg)
67+
raise PassageError.from_response_error(
68+
ApiException(status=404, data=Model404Error(code="user_not_found", error="User not found.")),
69+
)
6870

6971
return self.get(users[0].id)
7072

Diff for: tests/errors_test.py

-24
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,6 @@ def __init__(self, status: int, data: Model400Error | None, body: str | None = N
1212
self.body = body
1313

1414

15-
def test_error_with_all_values() -> None:
16-
error = PassageError("some message", 400, "Bad Request", {"error": "some error", "code": "some_error_code"})
17-
assert error.message == "some message"
18-
assert error.status_code == 400
19-
assert error.status_text == "Bad Request"
20-
assert error.error == "some error"
21-
assert error.error_code == "some_error_code"
22-
23-
24-
def test_error_with_only_message() -> None:
25-
error = PassageError("some message")
26-
assert error.message == "some message"
27-
assert error.status_code is None
28-
assert error.status_text is None
29-
assert error.error is None
30-
assert error.error_code is None
31-
32-
3315
def test_from_response_error() -> None:
3416
response_error = MockApiException(
3517
status=400,
@@ -40,8 +22,6 @@ def test_from_response_error() -> None:
4022
assert error.message == "some message: some error"
4123
assert error.status_code == 400
4224
assert error.error_code == "invalid_request"
43-
assert error.status_text is None
44-
assert error.error is None
4525

4626

4727
def test_from_response_error_without_message() -> None:
@@ -54,8 +34,6 @@ def test_from_response_error_without_message() -> None:
5434
assert error.message == "some error"
5535
assert error.status_code == 400
5636
assert error.error_code == "invalid_request"
57-
assert error.status_text is None
58-
assert error.error is None
5937

6038

6139
def test_from_response_error_without_data() -> None:
@@ -69,5 +47,3 @@ def test_from_response_error_without_data() -> None:
6947
assert error.message == "some error"
7048
assert error.status_code == 400
7149
assert error.error_code is None
72-
assert error.status_text is None
73-
assert error.error is None

0 commit comments

Comments
 (0)