from fastapi import Request, status from fastapi.responses import JSONResponse from fastapi.exceptions import RequestValidationError from starlette.exceptions import HTTPException as StarletteHTTPException import logging import time logger = logging.getLogger(__name__) class CoinCapAPIException(Exception): """Exception raised for CoinCap API errors.""" def __init__(self, status_code: int, detail: str): self.status_code = status_code self.detail = detail super().__init__(self.detail) async def validation_exception_handler(request: Request, exc: RequestValidationError): """Handle validation errors.""" logger.error(f"Validation error: {exc}") return JSONResponse( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, content={ "error": "Validation Error", "detail": exc.errors(), "timestamp": int(time.time() * 1000) } ) async def http_exception_handler(request: Request, exc: StarletteHTTPException): """Handle HTTP exceptions.""" logger.error(f"HTTP error: {exc.status_code} - {exc.detail}") return JSONResponse( status_code=exc.status_code, content={ "error": exc.detail, "timestamp": int(time.time() * 1000) } ) async def coincap_api_exception_handler(request: Request, exc: CoinCapAPIException): """Handle CoinCap API exceptions.""" logger.error(f"CoinCap API error: {exc.status_code} - {exc.detail}") return JSONResponse( status_code=exc.status_code, content={ "error": exc.detail, "timestamp": int(time.time() * 1000) } ) async def general_exception_handler(request: Request, exc: Exception): """Handle all other exceptions.""" logger.error(f"Unhandled exception: {exc}", exc_info=True) return JSONResponse( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={ "error": "Internal Server Error", "detail": str(exc), "timestamp": int(time.time() * 1000) } )