This commit is contained in:
Si Chen 2026-10-03 16:27:17 -04:00 • committed by GitHub
commit d71c4f4d79
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 116 additions and 9 deletions

View file

@ -122,7 +122,8 @@ class ExceptionCheckers:
known_exception_substrings: Final = [
"content_policy_violation",
"responsibleaipolicyviolation",
"the response was filtered due to the prompt triggering azure openai's content management",
"contentfiltered",
"the response was filtered due to the prompt triggering azure openai",
"your task failed as a result of our safety system",
"the model produced invalid content",
"content_filter_policy",
@ -1923,6 +1924,10 @@ def _map_vllm_exception(
)
_AZURE_CONTENT_POLICY_ERROR_CODES: Final = frozenset(("content_policy_violation", "content_filter"))
_AZURE_CONTENT_POLICY_INNER_CODES: Final = frozenset(("ResponsibleAIPolicyViolation", "ContentFiltered"))
def _map_azure_exception(
*,
model: str,
@ -1949,13 +1954,9 @@ def _map_azure_exception(
if isinstance(body_dict, dict):
if isinstance(body_dict.get("error"), dict):
azure_error_code = body_dict["error"].get("code")
# Also check inner_error for
# ResponsibleAIPolicyViolation which indicates a
# content policy violation even when the top-level
# code is generic (e.g. "invalid_request_error").
if azure_error_code != "content_policy_violation":
if azure_error_code not in _AZURE_CONTENT_POLICY_ERROR_CODES:
_inner: Final = body_dict["error"].get("inner_error") or body_dict["error"].get("innererror")
if isinstance(_inner, dict) and _inner.get("code") == "ResponsibleAIPolicyViolation":
if isinstance(_inner, dict) and _inner.get("code") in _AZURE_CONTENT_POLICY_INNER_CODES:
azure_error_code = "content_policy_violation"
else:
azure_error_code = body_dict.get("code")
@ -1986,8 +1987,9 @@ def _map_azure_exception(
litellm_debug_info=extra_information,
response=getattr(original_exception, "response", None),
)
elif azure_error_code == "content_policy_violation" or ExceptionCheckers.is_azure_content_policy_violation_error(
error_str
elif (
azure_error_code in _AZURE_CONTENT_POLICY_ERROR_CODES
or ExceptionCheckers.is_azure_content_policy_violation_error(error_str)
):
from litellm.llms.azure.exception_mapping import (
AzureOpenAIExceptionMapping,

View file

@ -171,9 +171,11 @@ class TestExceptionCheckers:
error_strings = [
"invalid_request_error content_policy_violation occurred",
"The response was filtered due to the prompt triggering Azure OpenAI's content management policy",
"The response was filtered due to the prompt triggering Azure OpenAI’s content management policy",
"Your task failed as a result of our safety system detecting harmful content",
"The model produced invalid content that violates our policy",
"Request blocked due to content_filter_policy restrictions",
"innererror code ContentFiltered",
]
for error_str in error_strings:
@ -186,8 +188,10 @@ class TestExceptionCheckers:
error_strings = [
"INVALID_REQUEST_ERROR CONTENT_POLICY_VIOLATION",
"The Response Was Filtered Due To The Prompt Triggering Azure OpenAI's Content Management",
"The Response Was Filtered Due To The Prompt Triggering Azure OpenAI’s Content Management",
"YOUR TASK FAILED AS A RESULT OF OUR SAFETY SYSTEM",
"Content_Filter_Policy restriction detected",
"CONTENTFILTERED",
]
for error_str in error_strings:

View file

@ -403,6 +403,107 @@ class TestAzureExceptionMapping:
assert "optional_pre_call_checks" in error.message
assert "docs.litellm.ai" in error.message
def test_azure_prompt_content_filter_maps_to_content_policy_violation(self):
mock_exception = Exception("Bad request")
mock_exception.body = {
"error": {
"message": (
"The response was filtered due to the prompt triggering "
"Azure OpenAI’s content management policy. Please modify your prompt and retry."
),
"type": "invalid_request_error",
"param": "prompt",
"code": "content_filter",
"content_filters": [
{
"blocked": True,
"source_type": "prompt",
"content_filter_results": {
"hate": {"filtered": False, "severity": "safe"},
"sexual": {"filtered": False, "severity": "safe"},
"violence": {"filtered": False, "severity": "safe"},
"self_harm": {"filtered": False, "severity": "safe"},
"jailbreak": {"detected": True, "filtered": True},
},
}
],
"innererror": {"code": "ContentFiltered"},
}
}
mock_response = MagicMock()
mock_response.status_code = 400
mock_exception.response = mock_response
with pytest.raises(ContentPolicyViolationError) as exc_info:
exception_type(
model="azure/gpt-4",
original_exception=mock_exception,
custom_llm_provider="azure",
)
e = exc_info.value
assert e.provider_specific_fields is not None
assert e.provider_specific_fields["innererror"]["code"] == "ContentFiltered"
assert e.provider_specific_fields["inner_error"]["code"] == "ContentFiltered"
def test_azure_content_filtered_innererror_without_top_code(self):
mock_exception = Exception("Bad request")
mock_exception.body = {
"error": {
"code": "invalid_request_error",
"innererror": {"code": "ContentFiltered"},
"message": "The request was rejected.",
"type": "invalid_request_error",
}
}
mock_response = MagicMock()
mock_response.status_code = 400
mock_exception.response = mock_response
with pytest.raises(ContentPolicyViolationError) as exc_info:
exception_type(
model="azure/gpt-4",
original_exception=mock_exception,
custom_llm_provider="azure",
)
e = exc_info.value
assert e.provider_specific_fields is not None
assert e.provider_specific_fields["innererror"]["code"] == "ContentFiltered"
def test_azure_ordinary_invalid_request_stays_bad_request(self):
from litellm.exceptions import BadRequestError
mock_exception = Exception(
"Error code: 400 - {'error': {'message': \"Invalid 'temperature': decimal above maximum value. "
"Expected a value <= 2, but got 200 instead.\", 'type': 'invalid_request_error', "
"'param': 'temperature', 'code': 'decimal_above_max_value'}}"
)
mock_exception.body = {
"error": {
"message": (
"Invalid 'temperature': decimal above maximum value. "
"Expected a value <= 2, but got 200 instead."
),
"type": "invalid_request_error",
"param": "temperature",
"code": "decimal_above_max_value",
}
}
mock_response = MagicMock()
mock_response.status_code = 400
mock_exception.response = mock_response
mock_exception.status_code = 400
with pytest.raises(BadRequestError) as exc_info:
exception_type(
model="azure/gpt-4",
original_exception=mock_exception,
custom_llm_provider="azure",
)
assert not isinstance(exc_info.value, ContentPolicyViolationError)
def test_openai_invalid_encrypted_content_error(self):
"""Test that OpenAI invalid_encrypted_content errors also get helpful guidance."""
from litellm.exceptions import BadRequestError