mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
Merge pull request #38624 from BerriAI/litellm_/circleci-regressions-review-f0a542
fix(exceptions): keep a refused connection an APIConnectionError
This commit is contained in:
commit
bd7e9c1997
5 changed files with 63 additions and 4 deletions
|
|
@ -2222,6 +2222,8 @@ def _map_exception_by_status(
|
|||
status_code: Final = original_exception.status_code if hasattr(original_exception, "status_code") else None
|
||||
if not isinstance(status_code, int) or status_code < 400:
|
||||
return
|
||||
if getattr(original_exception, "status_code_is_synthesized", False):
|
||||
return
|
||||
message: Final = f"{exception_provider} - {error_str}"
|
||||
response: Final = original_exception.response if hasattr(original_exception, "response") else None
|
||||
match status_code:
|
||||
|
|
|
|||
|
|
@ -46,8 +46,10 @@ class BaseLLMException(Exception):
|
|||
request: httpx.Request | None = None,
|
||||
response: httpx.Response | None = None,
|
||||
body: dict | None = None,
|
||||
status_code_is_synthesized: bool = False,
|
||||
):
|
||||
self.status_code = status_code
|
||||
self.status_code_is_synthesized = status_code_is_synthesized
|
||||
self.message: str = message
|
||||
self.headers = headers
|
||||
if request:
|
||||
|
|
|
|||
|
|
@ -5947,11 +5947,13 @@ class BaseLLMHTTPHandler:
|
|||
BaseEvalsAPIConfig,
|
||||
],
|
||||
):
|
||||
status_code = getattr(e, "status_code", 500)
|
||||
received_status_code: Final = (
|
||||
e.response.status_code if isinstance(e, httpx.HTTPStatusError) else getattr(e, "status_code", None)
|
||||
)
|
||||
status_code = received_status_code if isinstance(received_status_code, int) else 500
|
||||
error_headers = getattr(e, "headers", None)
|
||||
if isinstance(e, httpx.HTTPStatusError):
|
||||
error_text = e.response.text
|
||||
status_code = e.response.status_code
|
||||
else:
|
||||
error_text = getattr(e, "text", str(e))
|
||||
error_response: Final = getattr(e, "response", None)
|
||||
|
|
@ -5971,13 +5973,17 @@ class BaseLLMHTTPHandler:
|
|||
status_code=status_code,
|
||||
message=error_text,
|
||||
headers=error_headers,
|
||||
status_code_is_synthesized=not isinstance(received_status_code, int),
|
||||
)
|
||||
|
||||
raise provider_config.get_error_class(
|
||||
provider_error: Final = provider_config.get_error_class(
|
||||
error_message=error_text,
|
||||
status_code=status_code,
|
||||
headers=error_headers,
|
||||
)
|
||||
if not isinstance(received_status_code, int):
|
||||
provider_error.status_code_is_synthesized = True
|
||||
raise provider_error
|
||||
|
||||
@staticmethod
|
||||
def _append_query_params(url: str, query_params: RealtimeQueryParams | None) -> str:
|
||||
|
|
|
|||
|
|
@ -1163,3 +1163,52 @@ def test_bedrock_mantle_context_overflow_maps_to_context_window_exceeded():
|
|||
|
||||
assert excinfo.value.status_code == 400
|
||||
assert "prompt is too long: 1055489 tokens > 1050000 maximum" in excinfo.value.message
|
||||
|
||||
|
||||
def test_branchless_provider_transport_error_maps_to_api_connection_error():
|
||||
from litellm.llms.base_llm.chat.transformation import BaseLLMException
|
||||
|
||||
original_exception = BaseLLMException(status_code=500, message="[Errno 111] Connection refused")
|
||||
original_exception.status_code_is_synthesized = True
|
||||
|
||||
with pytest.raises(litellm.APIConnectionError):
|
||||
exception_type(
|
||||
model="test-agent",
|
||||
original_exception=original_exception,
|
||||
custom_llm_provider="a2a",
|
||||
)
|
||||
|
||||
|
||||
def test_branchless_provider_upstream_500_still_maps_to_internal_server_error():
|
||||
from litellm.llms.base_llm.chat.transformation import BaseLLMException
|
||||
|
||||
original_exception = BaseLLMException(status_code=500, message="upstream exploded")
|
||||
|
||||
with pytest.raises(litellm.InternalServerError):
|
||||
exception_type(
|
||||
model="test-agent",
|
||||
original_exception=original_exception,
|
||||
custom_llm_provider="a2a",
|
||||
)
|
||||
|
||||
|
||||
def test_handle_error_marks_only_a_status_code_it_never_received():
|
||||
from litellm.llms.custom_httpx.llm_http_handler import BaseLLMHTTPHandler
|
||||
|
||||
handler = BaseLLMHTTPHandler()
|
||||
|
||||
with pytest.raises(litellm.llms.base_llm.chat.transformation.BaseLLMException) as transport:
|
||||
raise handler._handle_error(e=httpx.ConnectError("Connection refused"), provider_config=None)
|
||||
assert transport.value.status_code == 500
|
||||
assert transport.value.status_code_is_synthesized is True
|
||||
|
||||
request = httpx.Request(method="POST", url="https://example.invalid")
|
||||
upstream = httpx.HTTPStatusError(
|
||||
"server error",
|
||||
request=request,
|
||||
response=httpx.Response(status_code=500, request=request, text="upstream exploded"),
|
||||
)
|
||||
with pytest.raises(litellm.llms.base_llm.chat.transformation.BaseLLMException) as received:
|
||||
raise handler._handle_error(e=upstream, provider_config=None)
|
||||
assert received.value.status_code == 500
|
||||
assert received.value.status_code_is_synthesized is False
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ async def test_query_param_key_not_leaked_with_dummy_caller_key(
|
|||
"litellm.llms.custom_httpx.http_handler.AsyncHTTPHandler.get",
|
||||
fake_get,
|
||||
):
|
||||
with pytest.raises(litellm.InternalServerError):
|
||||
with pytest.raises(litellm.APIConnectionError):
|
||||
await litellm.asearch(
|
||||
query="secrets",
|
||||
search_provider=provider,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue