fix(rust): preserve messages provider failures

This commit is contained in:
Yujong Lee 2026-09-08 08:28:52 -07:00
parent 42b8cd80be
commit d08d22642e
4 changed files with 25 additions and 12 deletions

View file

@ -5,7 +5,7 @@ from dataclasses import dataclass
from enum import Enum
from typing import Final, Generic, NoReturn, TypeAlias, TypeVar
from litellm.exceptions import APIError
from litellm.exceptions import APIError, InternalServerError
from litellm.rust_bridge.bindings import native_exception_types
NativeT = TypeVar("NativeT")
@ -142,6 +142,12 @@ def raise_upstream(error: BaseException, context: BridgeErrorContext) -> NoRetur
message_value: Final = args[1] if len(args) > 1 else str(error)
status: Final = status_value if isinstance(status_value, int) else 0
message: Final = message_value if isinstance(message_value, str) else str(message_value)
if status == 500:
raise InternalServerError(
message=f"litellm rust {context.route}: {message}",
llm_provider=context.provider,
model=context.model,
) from error
raise APIError(
status_code=status or 500,
message=f"litellm rust {context.route}: {message}",

View file

@ -4,7 +4,7 @@ from types import SimpleNamespace
import pytest
from litellm.exceptions import APIError
from litellm.exceptions import APIError, InternalServerError
from litellm.rust_bridge import bindings, runtime
@ -64,6 +64,22 @@ def test_invoke_translates_upstream_without_fallback() -> None:
assert caught.value.status_code == 429
def test_invoke_translates_internal_server_error_without_fallback() -> None:
def fail() -> object:
raise RustUpstreamError(500, "provider unavailable")
with pytest.raises(InternalServerError, match="provider unavailable") as caught:
runtime.invoke(
native_call=fail,
fallback=lambda: pytest.fail("fallback must not run"),
adapt=str,
mode=runtime.FallbackMode.PYTHON,
context=context(),
)
assert caught.value.status_code == 500
@pytest.mark.asyncio
async def test_ainvoke_handles_native_success() -> None:
async def native() -> int:

View file

@ -62,14 +62,7 @@ async def test_generic_api_logger_exports_success_over_http(route: Route, provid
"route",
(
OCR_ASYNC,
pytest.param(
MESSAGES_ROUTE,
marks=pytest.mark.xfail(
strict=True,
raises=pytest.fail.Exception,
reason="Native Messages provider failure raises TypeError and falls back to a second Python request",
),
),
MESSAGES_ROUTE,
),
ids=route_id,
)

View file

@ -1,6 +1,5 @@
import asyncio
import copy
import json
import threading
from typing import Final
@ -171,7 +170,6 @@ async def test_messages_logging_drain_waits_for_suspended_callback(messages_serv
@pytest.mark.asyncio
@pytest.mark.xfail(strict=True, reason="accepted native Messages errors are replayed through the Python transport")
async def test_messages_failure_callbacks_receive_original_provider_error(messages_server: RecordingServer) -> None:
messages_server.default_response = ResponseSpec(body={"error": {"message": "provider unavailable"}}, status=500)
messages_server.expected_requests = None