fix(passthrough): keep upstream error body readable for streaming error status mapping

This commit is contained in:
mateo-berri 2026-08-30 12:59:18 -07:00
parent ce52e39052
commit a5fa8ebfa7
3 changed files with 41 additions and 1 deletions

View file

@ -24342,7 +24342,7 @@
"supports_response_schema": true,
"supports_vision": true
},
"gigachat/GigaChat-2-Lite": {
"gigachat/GigaChat-2": {
"input_cost_per_token": 0.0,
"litellm_provider": "gigachat",
"max_input_tokens": 128000,
@ -24404,6 +24404,15 @@
"output_cost_per_token": 0.0,
"output_vector_size": 2560
},
"gigachat/GigaEmbeddings-3B-2025-09": {
"input_cost_per_token": 0.0,
"litellm_provider": "gigachat",
"max_input_tokens": 4096,
"max_tokens": 4096,
"mode": "embedding",
"output_cost_per_token": 0.0,
"output_vector_size": 2048
},
"gmi/anthropic/claude-opus-4.5": {
"input_cost_per_token": 5e-06,
"litellm_provider": "gmi",

View file

@ -86,6 +86,10 @@ class AsyncPassthroughStreamingResponse(AsyncGenerator[Any, Any]):
self._response.raise_for_status()
self._iterator = _as_async_generator(self._response.aiter_bytes())
except Exception: # noqa: BLE001 # Safe catch-all for cleanup logic
try:
await self._response.aread()
except Exception: # noqa: BLE001 S110 # Safe catch-all for cleanup logic
pass
try:
await self._response.aclose()
except Exception: # noqa: BLE001 S110 # Safe catch-all for cleanup logic

View file

@ -131,3 +131,30 @@ async def test_async_passthrough_wrapper_200_yields_chunks():
assert len(chunks) == 1
assert b"response.created" in chunks[0]
mock_logging_obj.async_flush_passthrough_collected_chunks.assert_awaited_once()
@pytest.mark.asyncio
async def test_error_body_readable_after_failed_await():
"""The upstream error body must stay readable so the proxy can map the real status and message."""
from litellm.passthrough.main import AsyncPassthroughStreamingResponse
error_body = b'{"message":"model not found"}'
async def byte_stream():
yield error_body
request = httpx.Request("POST", "https://bedrock.example.com/model/x/converse-stream")
response = httpx.Response(400, content=byte_stream(), request=request)
async def response_coro():
return response
with pytest.raises(httpx.HTTPStatusError) as exc_info:
await AsyncPassthroughStreamingResponse(
response=response_coro(),
litellm_logging_obj=_make_mock_logging_obj(),
provider_config=MagicMock(),
)
assert exc_info.value.response.status_code == 400
assert await exc_info.value.response.aread() == error_body