| """ | |
| Custom Exception Classes for Production Error Handling | |
| """ | |
| from typing import Any, Dict, Optional | |
| from fastapi import status | |
| class AppException(Exception): | |
| """Base application exception""" | |
| def __init__( | |
| self, | |
| message: str, | |
| status_code: int = status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| details: Optional[Dict[str, Any]] = None | |
| ): | |
| self.message = message | |
| self.status_code = status_code | |
| self.details = details or {} | |
| super().__init__(self.message) | |
| class ValidationError(AppException): | |
| """Validation error exception""" | |
| def __init__(self, message: str, details: Optional[Dict[str, Any]] = None): | |
| super().__init__( | |
| message=message, | |
| status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, | |
| details=details | |
| ) | |
| class AuthenticationError(AppException): | |
| """Authentication error exception""" | |
| def __init__(self, message: str = "Authentication failed"): | |
| super().__init__( | |
| message=message, | |
| status_code=status.HTTP_401_UNAUTHORIZED, | |
| details={"www_authenticate": "Bearer"} | |
| ) | |
| class AuthorizationError(AppException): | |
| """Authorization error exception""" | |
| def __init__(self, message: str = "Insufficient permissions"): | |
| super().__init__( | |
| message=message, | |
| status_code=status.HTTP_403_FORBIDDEN | |
| ) | |
| class ResourceNotFoundError(AppException): | |
| """Resource not found exception""" | |
| def __init__(self, resource: str, identifier: Any): | |
| super().__init__( | |
| message=f"{resource} not found", | |
| status_code=status.HTTP_404_NOT_FOUND, | |
| details={"resource": resource, "identifier": str(identifier)} | |
| ) | |
| class RateLimitExceededError(AppException): | |
| """Rate limit exceeded exception""" | |
| def __init__(self, limit: int, window: str): | |
| super().__init__( | |
| message=f"Rate limit exceeded: {limit} requests per {window}", | |
| status_code=status.HTTP_429_TOO_MANY_REQUESTS, | |
| details={"limit": limit, "window": window} | |
| ) | |
| class ModelLoadError(AppException): | |
| """ML model loading error""" | |
| def __init__(self, model_name: str, reason: str): | |
| super().__init__( | |
| message=f"Failed to load model: {model_name}", | |
| status_code=status.HTTP_503_SERVICE_UNAVAILABLE, | |
| details={"model": model_name, "reason": reason} | |
| ) | |
| class PredictionError(AppException): | |
| """ML prediction error""" | |
| def __init__(self, message: str, details: Optional[Dict[str, Any]] = None): | |
| super().__init__( | |
| message=message, | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| details=details | |
| ) | |
| class FileUploadError(AppException): | |
| """File upload error""" | |
| def __init__(self, message: str, details: Optional[Dict[str, Any]] = None): | |
| super().__init__( | |
| message=message, | |
| status_code=status.HTTP_400_BAD_REQUEST, | |
| details=details | |
| ) | |
| class DatabaseError(AppException): | |
| """Database operation error""" | |
| def __init__(self, message: str, details: Optional[Dict[str, Any]] = None): | |
| super().__init__( | |
| message=message, | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| details=details | |
| ) | |
| class CacheError(AppException): | |
| """Cache operation error""" | |
| def __init__(self, message: str, details: Optional[Dict[str, Any]] = None): | |
| super().__init__( | |
| message=message, | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| details=details | |
| ) | |