mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-16 23:41:43 +00:00
Merge pull request #40925 from BerriAI/litellm_proxy_error_headers_from_litellm_response_headers
fix(proxy): forward provider request id headers on mapped error responses
This commit is contained in:
commit
7c55c4ba7d
2 changed files with 39 additions and 6 deletions
|
|
@ -3452,15 +3452,13 @@ class ProxyBaseLLMRequestProcessing:
|
|||
# a failed request reports no timing, matching /v1/chat/completions
|
||||
read_timing_from_logging_obj=False,
|
||||
)
|
||||
# Extract headers from exception - check both e.headers and e.response.headers
|
||||
headers = getattr(e, "headers", None) or {}
|
||||
if not headers:
|
||||
# Try to get headers from e.response.headers (httpx.Response)
|
||||
_response: Final = attribute_of(e, "response")
|
||||
if _response is not None:
|
||||
_response_headers: Final = getattr(_response, "headers", None)
|
||||
if _response_headers:
|
||||
headers = get_response_headers(dict(_response_headers))
|
||||
_response_headers: Final = getattr(_response, "headers", None) if _response is not None else None
|
||||
_provider_headers: Final = _response_headers or getattr(e, "litellm_response_headers", None)
|
||||
if _provider_headers:
|
||||
headers = get_response_headers(dict(_provider_headers))
|
||||
headers.update(custom_headers)
|
||||
|
||||
# Call response headers hook for failure
|
||||
|
|
|
|||
|
|
@ -8400,6 +8400,41 @@ async def test_handle_llm_api_exception_forwards_provider_headers_on_http_status
|
|||
assert exc_info.value.headers["llm_provider-x-amzn-requestid"] == "req-passthrough-500"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_handle_llm_api_exception_forwards_litellm_response_headers_when_response_is_synthetic():
|
||||
"""Exception mapping hands the proxy a mapped error whose ``response`` is a synthetic empty
|
||||
``httpx.Response`` and parks the provider's real headers on ``litellm_response_headers``.
|
||||
The client must still get the provider request id, as it does on a 200.
|
||||
"""
|
||||
import httpx
|
||||
|
||||
from litellm.proxy._types import ProxyException, UserAPIKeyAuth
|
||||
|
||||
mapped = litellm.BadRequestError(
|
||||
message="OpenAIException - max_tokens is too large: 999999999.",
|
||||
model="gpt-4o-mini",
|
||||
llm_provider="openai",
|
||||
)
|
||||
mapped.litellm_response_headers = httpx.Headers({"x-request-id": "req_openai_400"})
|
||||
assert dict(mapped.response.headers) == {}
|
||||
|
||||
processor = ProxyBaseLLMRequestProcessing(data={})
|
||||
proxy_logging_obj = MagicMock()
|
||||
proxy_logging_obj.post_call_failure_hook = AsyncMock(return_value=None)
|
||||
proxy_logging_obj.post_call_response_headers_hook = AsyncMock(return_value={})
|
||||
|
||||
with pytest.raises(ProxyException) as exc_info:
|
||||
await processor._handle_llm_api_exception(
|
||||
e=mapped,
|
||||
user_api_key_dict=UserAPIKeyAuth(api_key="sk-test"),
|
||||
proxy_logging_obj=proxy_logging_obj,
|
||||
)
|
||||
|
||||
assert exc_info.value.code == "400"
|
||||
assert "max_tokens is too large: 999999999." in exc_info.value.message
|
||||
assert exc_info.value.headers["llm_provider-x-request-id"] == "req_openai_400"
|
||||
|
||||
|
||||
class TestBackgroundResponseRetrievalGovernance:
|
||||
"""LIT-7175: retrieving a background Response attaches the model's post_call policy pipelines."""
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue