diff --git a/seam/client.py b/seam/client.py index 9965e905..b4c00c30 100644 --- a/seam/client.py +++ b/seam/client.py @@ -61,6 +61,9 @@ def _handle_error_response(self, response: requests.Response): if status_code == 401: raise SeamHttpUnauthorizedError(request_id) + if not is_api_error_response(response): + response.raise_for_status() + error = response.json().get("error", {}) error_type = error.get("type", "unknown_error") error_message = error.get("message", "Unknown error") @@ -76,3 +79,32 @@ def _handle_error_response(self, response: requests.Response): raise SeamHttpInvalidInputError(error_details, status_code, request_id) raise SeamHttpApiError(error_details, status_code, request_id) + + +def is_api_error_response(response: requests.Response) -> bool: + try: + content_type = response.headers.get("content-type", "") + + if not isinstance(content_type, str) or not content_type.startswith( + "application/json" + ): + return False + + data = response.json() + except (ValueError, requests.exceptions.JSONDecodeError): + return False + + if not isinstance(data, dict): + return False + + error = data.get("error") + + if not isinstance(error, dict): + return False + + if not isinstance(error.get("type"), str) or not isinstance( + error.get("message"), str + ): + return False + + return True diff --git a/test/http_error_test.py b/test/http_error_test.py index 7474f811..27454229 100644 --- a/test/http_error_test.py +++ b/test/http_error_test.py @@ -1,4 +1,5 @@ import pytest +import niquests from seam import Seam from seam.exceptions import ( SeamHttpApiError, @@ -44,3 +45,18 @@ def test_seam_http_throws_invalid_input_error(server): assert err.status_code == 400 assert err.code == "invalid_input" assert err.request_id.startswith("request") + + +def test_seam_http_throws_http_error_on_non_standard_response(server): + endpoint, seed = server + seam = Seam.from_api_key(seed["seam_apikey1_token"], endpoint=endpoint) + + seam.client.post( + "/_fake/simulate_workspace_outage", + json={"workspace_id": seed["seed_workspace_1"], "routes": ["/devices/list"]}, + ) + + with pytest.raises(niquests.HTTPError) as exc_info: + seam.devices.list() + + assert exc_info.value.response.status_code == 503