Skip to content

Commit 1c94694

Browse files
authored
Merge pull request #553 from opsmill/copilot/fix-473
2 parents f321523 + 7858a62 commit 1c94694

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

changelog/473.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
JsonDecodeError now includes server response content in error message when JSON decoding fails, providing better debugging information for non-JSON server responses.

infrahub_sdk/exceptions.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ def __init__(self, message: str | None = None, content: str | None = None, url:
1717
self.url = url
1818
if not self.message and self.url:
1919
self.message = f"Unable to decode response as JSON data from {self.url}"
20+
if self.content:
21+
self.message += f". Server response: {self.content}"
2022
super().__init__(self.message)
2123

2224

tests/unit/sdk/test_utils.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
1+
import json
12
import tempfile
23
import uuid
34
from pathlib import Path
5+
from unittest.mock import Mock
46

57
import pytest
68
from graphql import parse
79
from whenever import Instant
810

11+
from infrahub_sdk.exceptions import JsonDecodeError
912
from infrahub_sdk.utils import (
1013
base16decode,
1114
base16encode,
1215
base36decode,
1316
base36encode,
1417
calculate_time_diff,
1518
compare_lists,
19+
decode_json,
1620
deep_merge_dict,
1721
dict_hash,
1822
duplicates,
@@ -227,3 +231,53 @@ def test_calculate_time_diff() -> None:
227231

228232
time5 = Instant.now().subtract(hours=77, minutes=12, seconds=34).format_common_iso()
229233
assert calculate_time_diff(time5) == "3d and 5h ago"
234+
235+
236+
def test_decode_json_success() -> None:
237+
"""Test decode_json with valid JSON response."""
238+
mock_response = Mock()
239+
mock_response.json.return_value = {"status": "ok", "data": {"key": "value"}}
240+
241+
result = decode_json(mock_response)
242+
assert result == {"status": "ok", "data": {"key": "value"}}
243+
244+
245+
def test_decode_json_failure_with_content() -> None:
246+
"""Test decode_json with invalid JSON response includes server content in error message."""
247+
mock_response = Mock()
248+
mock_response.json.side_effect = json.decoder.JSONDecodeError("Invalid JSON", "document", 0)
249+
mock_response.text = "Internal Server Error: Database connection failed"
250+
mock_response.url = "https://example.com/api/graphql"
251+
252+
with pytest.raises(JsonDecodeError) as exc_info:
253+
decode_json(mock_response)
254+
255+
error_message = str(exc_info.value)
256+
assert "Unable to decode response as JSON data from https://example.com/api/graphql" in error_message
257+
assert "Server response: Internal Server Error: Database connection failed" in error_message
258+
259+
260+
def test_decode_json_failure_without_content() -> None:
261+
"""Test decode_json with invalid JSON response and no content."""
262+
mock_response = Mock()
263+
mock_response.json.side_effect = json.decoder.JSONDecodeError("Invalid JSON", "document", 0)
264+
mock_response.text = ""
265+
mock_response.url = "https://example.com/api/graphql"
266+
267+
with pytest.raises(JsonDecodeError) as exc_info:
268+
decode_json(mock_response)
269+
270+
error_message = str(exc_info.value)
271+
assert "Unable to decode response as JSON data from https://example.com/api/graphql" in error_message
272+
# Should not include server response part when content is empty
273+
assert "Server response:" not in error_message
274+
275+
276+
def test_json_decode_error_custom_message() -> None:
277+
"""Test JsonDecodeError with custom message does not override custom message."""
278+
custom_message = "Custom error message"
279+
error = JsonDecodeError(message=custom_message, content="server error", url="https://example.com")
280+
281+
assert str(error) == custom_message
282+
assert error.content == "server error"
283+
assert error.url == "https://example.com"

0 commit comments

Comments
 (0)