free-claude-code/providers/error_mapping.py

56 lines
2.1 KiB
Python

"""Provider-specific exception mapping."""
import httpx
import openai
from core.anthropic import get_user_facing_error_message
from providers.exceptions import (
APIError,
AuthenticationError,
InvalidRequestError,
OverloadedError,
RateLimitError,
)
from providers.rate_limit import GlobalRateLimiter
def map_error(
e: Exception, *, rate_limiter: GlobalRateLimiter | None = None
) -> Exception:
"""Map OpenAI or HTTPX exception to specific ProviderError."""
message = get_user_facing_error_message(e)
limiter = rate_limiter or GlobalRateLimiter.get_instance()
if isinstance(e, openai.AuthenticationError):
return AuthenticationError(message, raw_error=str(e))
if isinstance(e, openai.RateLimitError):
limiter.set_blocked(60)
return RateLimitError(message, raw_error=str(e))
if isinstance(e, openai.BadRequestError):
return InvalidRequestError(message, raw_error=str(e))
if isinstance(e, openai.InternalServerError):
raw_message = str(e)
if "overloaded" in raw_message.lower() or "capacity" in raw_message.lower():
return OverloadedError(message, raw_error=raw_message)
return APIError(message, status_code=500, raw_error=str(e))
if isinstance(e, openai.APIError):
return APIError(
message, status_code=getattr(e, "status_code", 500), raw_error=str(e)
)
if isinstance(e, httpx.HTTPStatusError):
status = e.response.status_code
if status in (401, 403):
return AuthenticationError(message, raw_error=str(e))
if status == 429:
limiter.set_blocked(60)
return RateLimitError(message, raw_error=str(e))
if status == 400:
return InvalidRequestError(message, raw_error=str(e))
if status >= 500:
if status in (502, 503, 504):
return OverloadedError(message, raw_error=str(e))
return APIError(message, status_code=status, raw_error=str(e))
return APIError(message, status_code=status, raw_error=str(e))
return e