"""Standardized API exception classes for consistent error responses. Note: These exceptions use string detail for backward compatibility with existing tests. Future refactoring could standardize on structured error responses. """ from fastapi import HTTPException, status class APIError(HTTPException): """Base API error with consistent structure. Uses string detail for backward compatibility with existing tests. """ def __init__( self, status_code: int, message: str, ): super().__init__(status_code=status_code, detail=message) class NotFoundError(APIError): """Resource not found error (404).""" def __init__(self, resource: str): super().__init__( status_code=status.HTTP_404_NOT_FOUND, message=f"{resource} not found", ) class ConflictError(APIError): """Conflict error (409).""" def __init__(self, message: str): super().__init__( status_code=status.HTTP_409_CONFLICT, message=message, ) class BadRequestError(APIError): """Bad request error (400).""" def __init__(self, message: str): super().__init__( status_code=status.HTTP_400_BAD_REQUEST, message=message, ) class UnauthorizedError(APIError): """Unauthorized error (401).""" def __init__(self, message: str = "Not authenticated"): super().__init__( status_code=status.HTTP_401_UNAUTHORIZED, message=message, ) class ServiceUnavailableError(APIError): """Service unavailable error (503).""" def __init__(self, message: str): super().__init__( status_code=status.HTTP_503_SERVICE_UNAVAILABLE, message=message, ) class ValidationError(HTTPException): """Validation error (422) with field-specific errors.""" def __init__(self, message: str, field_errors: dict[str, str] | None = None): detail: dict[str, str | dict[str, str]] = {"message": message} if field_errors: detail["field_errors"] = field_errors super().__init__( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=detail, )