mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-30 01:52:18 +00:00
fix: propagate upstream status code in proxy API exception handler
When Google GenAI / Vertex returns a 404 for deprecated or missing models via streamGenerateContent, the exception was falling through to a generic handler that defaulted to 500. Now provider exceptions carrying a valid HTTP status_code correctly propagate it through to the ProxyException.
This commit is contained in:
parent
4cc3dd7aad
commit
e23728a6a5
2 changed files with 47 additions and 1 deletions
|
|
@ -1942,12 +1942,28 @@ class ProxyBaseLLMRequestProcessing:
|
|||
code=status.HTTP_400_BAD_REQUEST,
|
||||
headers=headers,
|
||||
)
|
||||
# Extract status_code from the exception if it carries one.
|
||||
# Provider exceptions (NotFoundError, BadRequestError, GeminiError,
|
||||
# VertexAIError, etc.) all have a status_code attribute reflecting
|
||||
# the upstream API response. Use it to return the correct HTTP code
|
||||
# instead of defaulting to 500.
|
||||
_exc_status_code = getattr(e, "status_code", None)
|
||||
if _exc_status_code is not None and isinstance(_exc_status_code, int) and 100 <= _exc_status_code <= 599:
|
||||
raise ProxyException(
|
||||
message=getattr(e, "message", error_msg),
|
||||
type=getattr(e, "type", "None"),
|
||||
param=getattr(e, "param", "None"),
|
||||
openai_code=getattr(e, "code", None),
|
||||
code=_exc_status_code,
|
||||
provider_specific_fields=getattr(e, "provider_specific_fields", None),
|
||||
headers=headers,
|
||||
)
|
||||
raise ProxyException(
|
||||
message=getattr(e, "message", error_msg),
|
||||
type=getattr(e, "type", "None"),
|
||||
param=getattr(e, "param", "None"),
|
||||
openai_code=getattr(e, "code", None),
|
||||
code=getattr(e, "status_code", 500),
|
||||
code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
provider_specific_fields=getattr(e, "provider_specific_fields", None),
|
||||
headers=headers,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2244,6 +2244,36 @@ class TestHandleLLMApiExceptionDictDetail:
|
|||
assert proxy_exc.message == "Content blocked by guardrail"
|
||||
assert proxy_exc.provider_specific_fields is None
|
||||
|
||||
async def test_not_found_error_preserves_404(self):
|
||||
"""NotFoundError with status_code=404 should map to ProxyException code=404."""
|
||||
from litellm.exceptions import NotFoundError
|
||||
|
||||
exc = NotFoundError(
|
||||
message="Model gemini-3.1-flash-lite-preview not found",
|
||||
model="gemini-3.1-flash-lite-preview",
|
||||
llm_provider="gemini",
|
||||
)
|
||||
proxy_exc = await self._invoke(exc)
|
||||
assert proxy_exc.code == "404"
|
||||
assert "NotFoundError" in proxy_exc.message
|
||||
|
||||
async def test_exception_with_status_code_propagates(self):
|
||||
"""Exception with a statically-set status_code should propagate it."""
|
||||
from litellm.llms.vertex_ai.common_utils import VertexAIError
|
||||
|
||||
exc = VertexAIError(
|
||||
status_code=429,
|
||||
message="Rate limit exceeded",
|
||||
)
|
||||
proxy_exc = await self._invoke(exc)
|
||||
assert proxy_exc.code == "429"
|
||||
|
||||
async def test_exception_without_status_code_defaults_to_500(self):
|
||||
"""Exception with no status_code attribute defaults to 500."""
|
||||
exc = ValueError("Something broke")
|
||||
proxy_exc = await self._invoke(exc)
|
||||
assert proxy_exc.code == "500"
|
||||
|
||||
|
||||
class TestAsyncStreamingDataGeneratorFastPath:
|
||||
"""Fast/slow path branching in async_streaming_data_generator."""
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue