Skip to content

Commit 36b25b2

Browse files
authored
Merge pull request #84 from tharropoulos/json-decode
fix(api): improve error handling for invalid JSON responses
2 parents 7b64166 + 5b32db0 commit 36b25b2

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

src/typesense/request_handler.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,10 @@ def _get_error_message(response: requests.Response) -> str:
260260
"""
261261
content_type = response.headers.get("Content-Type", "")
262262
if content_type.startswith("application/json"):
263-
err_message: str = response.json().get("message", "API error.")
264-
return err_message
263+
try:
264+
return typing.cast(str, response.json().get("message", "API error."))
265+
except requests.exceptions.JSONDecodeError:
266+
return f"API error: Invalid JSON response: {response.text}"
265267
return "API error."
266268

267269
@staticmethod

tests/api_call_test.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,41 @@ def test_get_exception() -> None:
9494
assert RequestHandler._get_exception(999) == exceptions.TypesenseClientError
9595

9696

97+
def test_get_error_message_with_invalid_json() -> None:
98+
"""Test that it correctly handles invalid JSON in error responses."""
99+
response = requests.Response()
100+
response.headers["Content-Type"] = "application/json"
101+
response.status_code = 400
102+
# Set an invalid JSON string that would cause JSONDecodeError
103+
response._content = b'{"message": "Error occurred", "details": {"key": "value"'
104+
105+
error_message = RequestHandler._get_error_message(response)
106+
assert "API error: Invalid JSON response:" in error_message
107+
assert '{"message": "Error occurred", "details": {"key": "value"' in error_message
108+
109+
110+
def test_get_error_message_with_valid_json() -> None:
111+
"""Test that it correctly extracts error message from valid JSON responses."""
112+
response = requests.Response()
113+
response.headers["Content-Type"] = "application/json"
114+
response.status_code = 400
115+
response._content = b'{"message": "Error occurred", "details": {"key": "value"}}'
116+
117+
error_message = RequestHandler._get_error_message(response)
118+
assert error_message == "Error occurred"
119+
120+
121+
def test_get_error_message_with_non_json_content_type() -> None:
122+
"""Test that it returns a default error message for non-JSON content types."""
123+
response = requests.Response()
124+
response.headers["Content-Type"] = "text/plain"
125+
response.status_code = 400
126+
response._content = b'Not a JSON content'
127+
128+
error_message = RequestHandler._get_error_message(response)
129+
assert error_message == "API error."
130+
131+
97132
def test_normalize_params_with_booleans() -> None:
98133
"""Test that it correctly normalizes boolean values to strings."""
99134
parameter_dict: typing.Dict[str, str | bool] = {"key1": True, "key2": False}

0 commit comments

Comments
 (0)