diff --git a/lago_python_client/services/response.py b/lago_python_client/services/response.py
index a699b5ba..1e6d9720 100644
--- a/lago_python_client/services/response.py
+++ b/lago_python_client/services/response.py
@@ -54,7 +54,13 @@ def verify_response(response: Response) -> Optional[Response]:
headers=response.headers,
)
- response_data: Any = from_json(response) # type: ignore
+ response_data: Any
+ try:
+ response_data = from_json(response) # type: ignore
+ except LagoApiError:
+ # The error body is not JSON, e.g. an HTML 502 page from a proxy or an
+ # empty body: keep the raw body and still report the real status code.
+ response_data = response.text or None
raise LagoApiError(
status_code=response.status_code,
url=str(response.request.url),
diff --git a/tests/test_response_services.py b/tests/test_response_services.py
index 26e47351..d25ead4b 100644
--- a/tests/test_response_services.py
+++ b/tests/test_response_services.py
@@ -85,6 +85,43 @@ def test_verify_response():
verify_response(response404)
+@pytest.mark.parametrize(
+ ("status_code", "content"),
+ [
+ (502, b"
502 Bad Gateway
"),
+ (503, b"upstream connect error"),
+ (404, b""),
+ ],
+)
+def test_verify_response_with_non_json_error_body(status_code, content):
+ """Keep the real status code and url when an error body is not JSON."""
+ # Given an error response whose body is not JSON (e.g. from a proxy)
+ url = "https://api.getlago.com/api/v1/customers/123"
+ response = Response(content=content, status_code=status_code, request=Request(method="GET", url=url))
+
+ # When service is applied
+ # Then the raised error carries the response status, url and raw body
+ with pytest.raises(LagoApiError) as exc_info:
+ verify_response(response)
+ assert exc_info.value.status_code == status_code
+ assert exc_info.value.url == url
+ assert exc_info.value.response == (content.decode() or None)
+
+
+def test_verify_response_with_json_error_body():
+ """Keep the decoded body of a JSON error response."""
+ # Given an error response with a JSON body
+ content = b'{"status":422,"error":"Unprocessable Entity","code":"validation_errors"}'
+ response = Response(content=content, status_code=422, request=Request(method="POST", url=""))
+
+ # When service is applied
+ # Then the raised error carries the decoded body
+ with pytest.raises(LagoApiError) as exc_info:
+ verify_response(response)
+ assert exc_info.value.status_code == 422
+ assert exc_info.value.response == {"status": 422, "error": "Unprocessable Entity", "code": "validation_errors"}
+
+
def test_get_response_data():
"""Get response data."""
# Given instanse of ``httpx.Response`` class with successful status code and content