diff --git a/sdks/python/pmxt/_hosted_errors.py b/sdks/python/pmxt/_hosted_errors.py index db8be016..1fcb36fc 100644 --- a/sdks/python/pmxt/_hosted_errors.py +++ b/sdks/python/pmxt/_hosted_errors.py @@ -3,6 +3,7 @@ from __future__ import annotations import json +import logging from collections.abc import Callable, Mapping, Sequence from typing import ClassVar, TYPE_CHECKING @@ -21,6 +22,9 @@ import httpx +logger = logging.getLogger(__name__) + + class HostedTradingError(PmxtError): """Root error for hosted trading failures returned by trade.pmxt.dev.""" @@ -178,7 +182,8 @@ def _matches_status(expected_status: int | None, status: int) -> bool: def _json_payload(response: httpx.Response) -> object | None: try: return response.json() - except ValueError: + except ValueError as exc: + logger.debug("Could not parse hosted response body as JSON: %s", exc) return None diff --git a/sdks/python/tests/test_hosted_errors.py b/sdks/python/tests/test_hosted_errors.py index 66c4dd02..618416a3 100644 --- a/sdks/python/tests/test_hosted_errors.py +++ b/sdks/python/tests/test_hosted_errors.py @@ -1,3 +1,5 @@ +import logging + import httpx import pytest @@ -256,3 +258,16 @@ def test_hosted_exceptions_also_catch_as_legacy_base(error_class, legacy_base): assert issubclass(error_class, legacy_base) assert issubclass(error_class, HostedTradingError) assert issubclass(error_class, PmxtError) + + +def test_malformed_response_body_is_logged_at_debug(caplog): + response = _response(500, text_body="502 Bad Gateway") + + with caplog.at_level(logging.DEBUG, logger="pmxt._hosted_errors"): + with pytest.raises(HostedTradingError): + raise_from_response(response) + + assert any( + "Could not parse hosted response body as JSON" in record.message + for record in caplog.records + )