Skip to content

Commit 1aec6cd

Browse files
echarrodclaude
andauthored
fix: Raise error for non-JSON-serializable parameters (#70)
* client: Raise error for non-JSON-serializable parameters Fixes issue #69 by providing clear error messages when parameters cannot be serialized to JSON, instead of silently suppressing the error. Changes: - Catch only TypeError instead of all Exceptions when serializing parameters - Raise TypeError with descriptive message for non-serializable types - Add test cases for Decimal and custom objects - Verify None requests still work correctly 🤖 Generated with Claude Code Co-Authored-By: Claude <[email protected]> * client: Preserve original exception chain --------- Co-authored-by: Claude <[email protected]>
1 parent 78ae253 commit 1aec6cd

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

luno_python/base_client.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,13 @@ def do(self, method, path, req=None, auth=False):
7070
:type req: object
7171
:type auth: bool
7272
"""
73-
try:
74-
params = json.loads(json.dumps(req))
75-
except Exception:
73+
if req is None:
7674
params = None
75+
else:
76+
try:
77+
params = json.loads(json.dumps(req))
78+
except TypeError as e:
79+
raise TypeError("luno: request parameters must be JSON-serializable: %s" % str(e)) from e
7780
headers = {"User-Agent": self.make_user_agent()}
7881
args = dict(timeout=self.timeout, params=params, headers=headers)
7982
if auth:

tests/test_client.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from decimal import Decimal
2+
13
import pytest
24
import requests
35
import requests_mock
@@ -262,3 +264,29 @@ def test_get_balances_with_malformed_response():
262264
# Test without account_id on malformed response
263265
result = c.get_balances()
264266
assert result == MOCK_MALFORMED_RESPONSE
267+
268+
269+
def test_client_do_with_non_serializable_params():
270+
"""Test that non-JSON-serializable parameters raise a clear error."""
271+
c = Client()
272+
c.set_base_url("mock://test/")
273+
274+
# Test with Decimal (not JSON-serializable)
275+
with pytest.raises(TypeError) as exc_info:
276+
c.do("GET", "/", req={"amount": Decimal("10.5")})
277+
assert "JSON-serializable" in str(exc_info.value)
278+
279+
# Test with custom object (not JSON-serializable)
280+
class CustomObject:
281+
pass
282+
283+
with pytest.raises(TypeError) as exc_info:
284+
c.do("GET", "/", req={"obj": CustomObject()})
285+
assert "JSON-serializable" in str(exc_info.value)
286+
287+
# Test with None request (should not raise)
288+
adapter = requests_mock.Adapter()
289+
c.session.mount("mock", adapter)
290+
adapter.register_uri("GET", "mock://test/", json={"result": "ok"})
291+
result = c.do("GET", "/", req=None)
292+
assert result["result"] == "ok"

0 commit comments

Comments
 (0)