Skip to content

Commit 2df90cc

Browse files
committed
fix(client): preserve original exception context with from clause
ClientError was wrapping caught exceptions without chaining them, discarding the original traceback. Added `from e` to both raise sites so the root cause is visible when debugging.
1 parent 6c493bd commit 2df90cc

2 files changed

Lines changed: 7 additions & 4 deletions

File tree

kanboard.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ def _parse_response(response: bytes) -> Any:
166166

167167
return body.get("result")
168168
except ValueError as e:
169-
raise ClientError(f"Failed to parse JSON response: {e}")
169+
raise ClientError(f"Failed to parse JSON response: {e}") from e
170170

171171
def _do_request(self, headers: Dict[str, str], body: Dict[str, Any]) -> Any:
172172
try:
@@ -182,7 +182,7 @@ def _do_request(self, headers: Dict[str, str], body: Dict[str, Any]) -> Any:
182182

183183
response = http.urlopen(request, context=ssl_context, timeout=self._timeout).read()
184184
except Exception as e:
185-
raise ClientError(str(e))
185+
raise ClientError(str(e)) from e
186186
return self._parse_response(response)
187187

188188
def execute(self, method: str, **kwargs: Any) -> Any:

tests/test_kanboard.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,11 @@ def test_custom_auth_header(self):
5252
assert kwargs["headers"]["X-Auth-Header"] == "dXNlcm5hbWU6cGFzc3dvcmQ="
5353

5454
def test_http_error(self):
55-
self.urlopen.side_effect = Exception()
56-
with self.assertRaises(kanboard.ClientError):
55+
original = Exception("connection refused")
56+
self.urlopen.side_effect = original
57+
with self.assertRaises(kanboard.ClientError) as cm:
5758
self.client.remote_procedure()
59+
self.assertIs(cm.exception.__cause__, original)
5860

5961
def test_empty_response_raises_client_error(self):
6062
self.urlopen.return_value.read.return_value = b""
@@ -68,6 +70,7 @@ def test_json_parsing_failure(self):
6870
with self.assertRaises(kanboard.ClientError) as cm:
6971
self.client.remote_procedure()
7072
self.assertIn("Failed to parse JSON response", str(cm.exception))
73+
self.assertIsInstance(cm.exception.__cause__, ValueError)
7174

7275
def test_application_error(self):
7376
body = b'{"jsonrpc": "2.0", "error": {"code": -32603, "message": "Internal error"}, "id": 123}'

0 commit comments

Comments
 (0)