| """Unified exception hierarchy for providers.""" | |
| from typing import Any | |
| class ProviderError(Exception): | |
| """Base exception for all provider errors.""" | |
| def __init__( | |
| self, | |
| message: str, | |
| status_code: int = 500, | |
| error_type: str = "api_error", | |
| raw_error: Any = None, | |
| ): | |
| super().__init__(message) | |
| self.message = message | |
| self.status_code = status_code | |
| self.error_type = error_type | |
| self.raw_error = raw_error | |
| def to_anthropic_format(self) -> dict: | |
| """Convert to Anthropic-compatible error response.""" | |
| return { | |
| "type": "error", | |
| "error": { | |
| "type": self.error_type, | |
| "message": self.message, | |
| }, | |
| } | |
| class AuthenticationError(ProviderError): | |
| """Raised when API key is invalid or missing.""" | |
| def __init__(self, message: str, raw_error: Any = None): | |
| super().__init__( | |
| message, | |
| status_code=401, | |
| error_type="authentication_error", | |
| raw_error=raw_error, | |
| ) | |
| class InvalidRequestError(ProviderError): | |
| """Raised when the request parameters are invalid.""" | |
| def __init__(self, message: str, raw_error: Any = None): | |
| super().__init__( | |
| message, | |
| status_code=400, | |
| error_type="invalid_request_error", | |
| raw_error=raw_error, | |
| ) | |
| class RateLimitError(ProviderError): | |
| """Raised when rate limit is exceeded.""" | |
| def __init__(self, message: str, raw_error: Any = None): | |
| super().__init__( | |
| message, | |
| status_code=429, | |
| error_type="rate_limit_error", | |
| raw_error=raw_error, | |
| ) | |
| class OverloadedError(ProviderError): | |
| """Raised when the provider is overloaded.""" | |
| def __init__(self, message: str, raw_error: Any = None): | |
| super().__init__( | |
| message, | |
| status_code=529, | |
| error_type="overloaded_error", | |
| raw_error=raw_error, | |
| ) | |
| class APIError(ProviderError): | |
| """Raised when the provider returns a generic API error.""" | |
| def __init__(self, message: str, status_code: int = 500, raw_error: Any = None): | |
| super().__init__( | |
| message, | |
| status_code=status_code, | |
| error_type="api_error", | |
| raw_error=raw_error, | |
| ) | |