from typing import Any, Dict, Optional from fastapi import HTTPException, status class InvoiceAppException(HTTPException): """Base exception for the invoicing application.""" def __init__( self, status_code: int, detail: Any = None, headers: Optional[Dict[str, Any]] = None, ) -> None: super().__init__(status_code=status_code, detail=detail, headers=headers) class NotFoundException(InvoiceAppException): """Exception raised when a resource is not found.""" def __init__( self, detail: Any = "Resource not found", headers: Optional[Dict[str, Any]] = None, ) -> None: super().__init__( status_code=status.HTTP_404_NOT_FOUND, detail=detail, headers=headers, ) class UnauthorizedException(InvoiceAppException): """Exception raised when user is not authenticated.""" def __init__( self, detail: Any = "Not authenticated", headers: Optional[Dict[str, Any]] = None, ) -> None: super().__init__( status_code=status.HTTP_401_UNAUTHORIZED, detail=detail, headers=headers or {"WWW-Authenticate": "Bearer"}, ) class ForbiddenException(InvoiceAppException): """Exception raised when user does not have permission.""" def __init__( self, detail: Any = "Not enough permissions", headers: Optional[Dict[str, Any]] = None, ) -> None: super().__init__( status_code=status.HTTP_403_FORBIDDEN, detail=detail, headers=headers, ) class BadRequestException(InvoiceAppException): """Exception raised for bad requests.""" def __init__( self, detail: Any = "Bad request", headers: Optional[Dict[str, Any]] = None, ) -> None: super().__init__( status_code=status.HTTP_400_BAD_REQUEST, detail=detail, headers=headers, )