Revert "[Feature]: Replace HTTPException with ParallelRequestLimitError in pa…" (#15095)

This reverts commit 71b9b58fa9.
This commit is contained in:
Ishaan Jaff
2025-09-30 21:17:04 -07:00
committed by GitHub
parent 395c32c38d
commit 73bfef1a1f
4 changed files with 10 additions and 56 deletions
-1
View File
@@ -1301,7 +1301,6 @@ from .exceptions import (
ImageFetchError,
NotFoundError,
RateLimitError,
ParallelRequestLimitError,
ServiceUnavailableError,
OpenAIError,
ContextWindowExceededError,
-44
View File
@@ -353,49 +353,6 @@ class RateLimitError(openai.RateLimitError): # type: ignore
return _message
class ParallelRequestLimitError(RateLimitError): # type: ignore
def __init__(
self,
message: str,
llm_provider: Optional[str] = "litellm",
model: Optional[str] = "unknown",
headers: Optional[dict] = None,
response: Optional[httpx.Response] = None,
litellm_debug_info: Optional[str] = None,
max_retries: Optional[int] = None,
num_retries: Optional[int] = None,
):
# Store headers for later access (similar to FastAPI HTTPException)
self.headers = headers or {}
# Create a response with custom headers if provided
if response is None:
response_headers = headers
response = httpx.Response(
status_code=429,
headers=response_headers,
request=httpx.Request(
method="POST",
url="https://litellm.ai/parallel-request-limiter",
),
)
# Initialize parent with appropriate defaults for parallel request limiting
super().__init__(
message=message,
llm_provider=llm_provider or "litellm",
model=model or "unknown",
response=response,
litellm_debug_info=litellm_debug_info,
max_retries=max_retries,
num_retries=num_retries,
)
# Update the message prefix to be more specific
self.message = "litellm.ParallelRequestLimitError: {}".format(message)
self.detail = message # Store original detail for FastAPI compatibility
# sub class of rate limit error - meant to give more granularity for error handling context window exceeded errors
class ContextWindowExceededError(BadRequestError): # type: ignore
def __init__(
@@ -791,7 +748,6 @@ LITELLM_EXCEPTION_TYPES = [
Timeout,
PermissionDeniedError,
RateLimitError,
ParallelRequestLimitError,
ContextWindowExceededError,
RejectedRequestError,
ContentPolicyViolationError,
@@ -22,7 +22,6 @@ from typing import (
from litellm import DualCache
from litellm._logging import verbose_proxy_logger
from litellm.exceptions import ParallelRequestLimitError
from litellm.integrations.custom_logger import CustomLogger
from litellm.proxy._types import UserAPIKeyAuth
from litellm.types.llms.openai import BaseLiteLLMOpenAIResponseObject
@@ -701,8 +700,9 @@ class _PROXY_MaxParallelRequestsHandler_v3(CustomLogger):
f"Limit resets at: {reset_time_formatted}"
)
raise ParallelRequestLimitError(
message=detail,
raise HTTPException(
status_code=429,
detail=detail,
headers={
"retry-after": str(self.window_size),
"rate_limit_type": str(status["rate_limit_type"]),
@@ -14,7 +14,6 @@ from fastapi import HTTPException
import litellm
from litellm import Router
from litellm.caching.caching import DualCache
from litellm.exceptions import ParallelRequestLimitError
from litellm.proxy._types import UserAPIKeyAuth
from litellm.proxy.hooks.parallel_request_limiter_v3 import (
_PROXY_MaxParallelRequestsHandler_v3 as _PROXY_MaxParallelRequestsHandler,
@@ -93,7 +92,7 @@ async def test_sliding_window_rate_limit_v3(monkeypatch):
)
# Fourth request should fail (counter would be 4, limit is 3, so 4 > 3)
with pytest.raises(ParallelRequestLimitError) as exc_info:
with pytest.raises(HTTPException) as exc_info:
await parallel_request_handler.async_pre_call_hook(
user_api_key_dict=user_api_key_dict,
cache=local_cache,
@@ -375,7 +374,7 @@ async def test_normal_router_call_tpm_v3(monkeypatch, rate_limit_object):
await local_cache.async_increment_cache(key=counter_key, value=15, ttl=2) # Use up most of our 10 token limit
# Make another request to test rate limiting - this should fail as we've consumed tokens
with pytest.raises(ParallelRequestLimitError) as exc_info:
with pytest.raises(HTTPException) as exc_info:
await parallel_request_handler.async_pre_call_hook(
user_api_key_dict=user_api_key_dict,
cache=local_cache,
@@ -778,7 +777,7 @@ async def test_tpm_api_key_rate_limits_v3():
async def mock_should_rate_limit(descriptors, **kwargs):
nonlocal captured_descriptors
captured_descriptors = descriptors
# Return Error response to ensure ParallelRequestLimitError
# Return Error response to ensure HTTPException
return {
"overall_code": "OVER_LIMIT",
"statuses": [{'code': 'OK', 'current_limit': 2, 'limit_remaining': 1, 'rate_limit_type': 'requests', 'descriptor_key': 'model_per_key'},
@@ -796,7 +795,7 @@ async def test_tpm_api_key_rate_limits_v3():
data={"model": model},
call_type="",
)
except ParallelRequestLimitError as e:
except HTTPException as e:
error=e
assert e.status_code == 429
assert "rate_limit_type" in e.headers
@@ -854,7 +853,7 @@ async def test_rpm_api_key_rate_limits_v3():
async def mock_should_rate_limit(descriptors, **kwargs):
nonlocal captured_descriptors
captured_descriptors = descriptors
# Return Error response to ensure ParallelRequestLimitError
# Return Error response to ensure HTTPException
return {
"overall_code": "OVER_LIMIT",
"statuses": [{'code': 'OVER_LIMIT', 'current_limit': 2, 'limit_remaining': -2, 'rate_limit_type': 'requests', 'descriptor_key': 'model_per_key'},
@@ -872,7 +871,7 @@ async def test_rpm_api_key_rate_limits_v3():
data={"model": model},
call_type="",
)
except ParallelRequestLimitError as e:
except HTTPException as e:
error=e
assert e.status_code == 429
assert "rate_limit_type" in e.headers
@@ -923,7 +922,7 @@ async def test_team_member_rate_limits_v3():
async def mock_should_rate_limit(descriptors, **kwargs):
nonlocal captured_descriptors
captured_descriptors = descriptors
# Return OK response to avoid ParallelRequestLimitError
# Return OK response to avoid HTTPException
return {
"overall_code": "OK",
"statuses": []