This commit is contained in:
DltsumCtnori 2026-10-18 16:09:58 +00:00 • committed by GitHub
commit 249be5cfc9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 20 additions and 1 deletions

View file

@ -703,13 +703,16 @@ def proxy_exception_from_http_exception(exc: HTTPException, headers: dict[str, s
existing_fields: Final = getattr(exc, "provider_specific_fields", None) or {}
merged_fields: Final = {**existing_fields, **structured_fields} if structured_fields else (existing_fields or None)
error_status: Final = error_status_code(exc, status.HTTP_400_BAD_REQUEST)
# Preserve headers carried on the HTTPException itself (e.g. `retry-after`
# set by the rate limiter on 429); caller-supplied headers win on conflict.
merged_headers: Final = {**(exc.headers or {}), **headers}
return ProxyException(
message=message,
type=openai_error_type(exc, error_status),
param=openai_error_param(exc),
code=error_status,
provider_specific_fields=merged_fields,
headers=headers,
headers=merged_headers,
)

View file

@ -2380,6 +2380,22 @@ class TestCommonRequestProcessingHelpers:
assert plain.code == "429"
assert plain.provider_specific_fields is None
async def test_proxy_exception_from_http_exception_preserves_exc_headers(self):
"""Headers carried on the HTTPException itself (e.g. `retry-after` set by
the rate limiter on 429) must survive the conversion to ProxyException;
caller-supplied headers win on conflict."""
from litellm.proxy.common_request_processing import (
proxy_exception_from_http_exception,
)
exc = HTTPException(status_code=429, detail="slow down", headers={"retry-after": "60"})
result = proxy_exception_from_http_exception(exc, {"x-litellm-call-id": "abc"})
assert result.headers == {"retry-after": "60", "x-litellm-call-id": "abc"}
conflict = HTTPException(status_code=429, detail="slow down", headers={"retry-after": "60"})
overridden = proxy_exception_from_http_exception(conflict, {"retry-after": "30"})
assert overridden.headers == {"retry-after": "30"}
async def test_proxy_exception_from_route_error_helper(self) -> None:
"""The shared route error -> ProxyException conversion keeps the status an exception
carries, never the OpenAI SDK's ``code`` field (``None`` on most litellm exceptions)."""