Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add payload to ClientError and structure message #242

Merged
merged 2 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion src/posit/connect/errors.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
import json
from typing import Any


class ClientError(Exception):
def __init__(
self,
error_code: int,
error_message: str,
http_status: int,
http_message: str,
payload: Any = None,
):
self.error_code = error_code
self.error_message = error_message
self.http_status = http_status
self.http_message = http_message
self.payload = payload
super().__init__(
f"{error_message} (Error Code: {error_code}, HTTP Status: {http_status} {http_message})"
json.dumps(
{
"error_code": error_code,
"error_message": error_message,
"http_status": http_status,
"http_message": http_message,
"payload": payload,
}
)
)
3 changes: 2 additions & 1 deletion src/posit/connect/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ def handle_errors(response: Response, *args, **kwargs) -> Response:
data = response.json()
error_code = data["code"]
message = data["error"]
payload = data.get("payload")
http_status = response.status_code
http_status_message = responses[http_status]
raise ClientError(
error_code, message, http_status, http_status_message
error_code, message, http_status, http_status_message, payload
)
except JSONDecodeError:
# No JSON error message from Connect, so just raise
Expand Down
69 changes: 53 additions & 16 deletions tests/posit/connect/test_errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,56 @@
from posit.connect.errors import ClientError


class TestClientError:
def test(self):
error_code = 0
error_message = "foo"
http_status = 404
http_message = "Foo Bar"
with pytest.raises(
ClientError,
match=r"foo \(Error Code: 0, HTTP Status: 404 Foo Bar\)",
):
raise ClientError(
error_code=error_code,
error_message=error_message,
http_status=http_status,
http_message=http_message,
)
def test():
error_code = 0
error_message = "error"
http_status = 404
http_message = "Error"
with pytest.raises(
ClientError,
match='{"error_code": 0, "error_message": "error", "http_status": 404, "http_message": "Error", "payload": null}',
):
raise ClientError(
error_code=error_code,
error_message=error_message,
http_status=http_status,
http_message=http_message,
)


def test_payload_is_str():
error_code = 0
error_message = "error"
http_status = 404
http_message = "Error"
payload = "This is an error payload"
with pytest.raises(
ClientError,
match='{"error_code": 0, "error_message": "error", "http_status": 404, "http_message": "Error", "payload": "This is an error payload"}',
):
raise ClientError(
error_code=error_code,
error_message=error_message,
http_status=http_status,
http_message=http_message,
payload=payload,
)


def test_payload_is_dict():
error_code = 0
error_message = "error"
http_status = 404
http_message = "Error"
payload = {"message": "This is an error payload"}
with pytest.raises(
ClientError,
match='{"error_code": 0, "error_message": "error", "http_status": 404, "http_message": "Error", "payload": {"message": "This is an error payload"}}',
):
raise ClientError(
error_code=error_code,
error_message=error_message,
http_status=http_status,
http_message=http_message,
payload=payload,
)
2 changes: 1 addition & 1 deletion tests/posit/connect/test_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def test_response_client_error_with_json_payload():
response.raw = io.BytesIO(b'{"code":0,"error":"foobar"}')
with pytest.raises(
ClientError,
match=r"foobar \(Error Code: 0, HTTP Status: 400 Bad Request\)",
match='{"error_code": 0, "error_message": "foobar", "http_status": 400, "http_message": "Bad Request", "payload": null}',
):
handle_errors(response)

Expand Down
Loading