Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ddtrace/appsec/ai_guard/_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ def evaluate(self, messages: list[Message], options: Optional[Options] = None) -

try:
response = self._execute_request(f"{self._endpoint}/evaluate", payload)
result = response.get_json()
result = response.get_json() or {}
except Exception as e:
raise AIGuardClientError(message=f"Unexpected error calling AI Guard service: {e}") from e

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fixes:
- |
ai_guard: Fix TypeError while processing failed AI Guard responses, leading to overriding the original error.

18 changes: 18 additions & 0 deletions tests/appsec/ai_guard/api/test_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,24 @@ def test_evaluate_http_error(mock_execute_request, telemetry_mock, ai_guard_clie
assert_telemetry(telemetry_mock, "ai_guard.requests", (("error", "true"),))


@patch("ddtrace.internal.telemetry.telemetry_writer._namespace")
@patch("ddtrace.appsec.ai_guard._api_client.AIGuardClient._execute_request")
def test_evaluate_http_error_empty_json_body(mock_execute_request, telemetry_mock, ai_guard_client):
"""Test HTTP error handling when the response body is empty."""
mock_response = Mock()
mock_response.status = 500
mock_response.get_json.return_value = None
mock_execute_request.return_value = mock_response

with pytest.raises(AIGuardClientError) as exc_info:
ai_guard_client.evaluate(TOOL_CALL)

assert str(exc_info.value) == "AI Guard service call failed, status: 500"
assert exc_info.value.status == 500
assert exc_info.value.errors == []
assert_telemetry(telemetry_mock, "ai_guard.requests", (("error", "true"),))
Comment on lines +176 to +189
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test only covers the case when status is 500 with an empty JSON body. Consider adding a test case for status 200 with an empty JSON body to ensure that the malformed response error handler works correctly in this scenario. While the existing try-except block at line 250 in the source code should handle this case properly, having an explicit test would provide better coverage and documentation of this edge case.

Copilot uses AI. Check for mistakes.


@patch("ddtrace.internal.telemetry.telemetry_writer._namespace")
@patch("ddtrace.appsec.ai_guard._api_client.AIGuardClient._execute_request")
def test_evaluate_invalid_json(mock_execute_request, telemetry_mock, ai_guard_client):
Expand Down