mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
fix(logging): keep proxy-side rate limits as expected client errors
ProxyRateLimitError derives from HTTPException but carries an llm_provider, so it read as provider-originated and regained its traceback. Any HTTPException is a proxy rejection regardless of llm_provider.
This commit is contained in:
parent
ac6deec529
commit
a6e1708e6c
2 changed files with 19 additions and 0 deletions
|
|
@ -58,7 +58,17 @@ def safe_divide(
|
|||
return numerator / denominator
|
||||
|
||||
|
||||
def _is_proxy_rejection(exception: BaseException) -> bool:
|
||||
try:
|
||||
from starlette.exceptions import HTTPException
|
||||
except ImportError:
|
||||
return False
|
||||
return isinstance(exception, HTTPException)
|
||||
|
||||
|
||||
def _is_provider_originated(exception: BaseException) -> bool:
|
||||
if _is_proxy_rejection(exception):
|
||||
return False
|
||||
if getattr(exception, "llm_provider", None):
|
||||
return True
|
||||
from litellm.llms.base_llm.chat.transformation import BaseLLMException
|
||||
|
|
@ -74,6 +84,8 @@ def is_expected_client_error(exception: BaseException | None) -> bool:
|
|||
client error and keeps its traceback: a mapped litellm exception carries
|
||||
``llm_provider``, and the raw ``BaseLLMException`` that provider handlers
|
||||
raise before mapping (the /v1/messages route surfaces it as-is) is one too.
|
||||
The proxy's own limiters raise ``HTTPException`` subclasses that also carry
|
||||
an ``llm_provider``, so any ``HTTPException`` stays a proxy rejection.
|
||||
|
||||
ProxyException stores the status on .code (as a str), HTTPException and
|
||||
litellm exceptions on .status_code.
|
||||
|
|
|
|||
|
|
@ -286,6 +286,7 @@ class TestIsExpectedClientError:
|
|||
from litellm.exceptions import AuthenticationError, RateLimitError
|
||||
from litellm.litellm_core_utils.core_helpers import is_expected_client_error
|
||||
from litellm.llms.anthropic.common_utils import AnthropicError
|
||||
from litellm.proxy.common_utils.proxy_rate_limit_error import ProxyRateLimitError
|
||||
|
||||
provider_auth_failure = AuthenticationError(
|
||||
message="AnthropicException - API key is invalid.", llm_provider="anthropic", model="claude-haiku-4-5"
|
||||
|
|
@ -298,6 +299,12 @@ class TestIsExpectedClientError:
|
|||
unmapped_provider_failure = AnthropicError(status_code=401, message='{"type":"authentication_error"}')
|
||||
assert is_expected_client_error(unmapped_provider_failure) is False
|
||||
|
||||
proxy_rate_limit = ProxyRateLimitError(
|
||||
detail={"error": "Max parallel requests reached"}, model="claude-haiku-4-5", llm_provider="anthropic"
|
||||
)
|
||||
assert proxy_rate_limit.llm_provider == "anthropic"
|
||||
assert is_expected_client_error(proxy_rate_limit) is True
|
||||
|
||||
class RouterRejection(Exception):
|
||||
def __init__(self):
|
||||
self.status_code = 429
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue