| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 | # (c) Nelen & Schuurmansimport loggingfrom typing import Listfrom typing import Optionalfrom typing import Unionfrom fastapi.encoders import jsonable_encoderfrom fastapi.requests import Requestfrom fastapi.responses import JSONResponsefrom starlette import statusfrom clean_python import BadRequestfrom clean_python import Conflictfrom clean_python import DoesNotExistfrom clean_python import PermissionDeniedfrom clean_python import Unauthorizedfrom clean_python import ValueObjectlogger = logging.getLogger(__name__)__all__ = [    "ValidationErrorResponse",    "DefaultErrorResponse",    "not_found_handler",    "conflict_handler",    "validation_error_handler",    "permission_denied_handler",    "unauthorized_handler",]class ValidationErrorEntry(ValueObject):    loc: List[Union[str, int]]    msg: str    type: strclass ValidationErrorResponse(ValueObject):    message: str    detail: List[ValidationErrorEntry]class DefaultErrorResponse(ValueObject):    message: str    detail: Optional[str]async def not_found_handler(request: Request, exc: DoesNotExist) -> JSONResponse:    return JSONResponse(        status_code=status.HTTP_404_NOT_FOUND,        content={            "message": f"Could not find {exc.name}{' with id=' + str(exc.id) if exc.id else ''}"        },    )async def conflict_handler(request: Request, exc: Conflict) -> JSONResponse:    return JSONResponse(        status_code=status.HTTP_409_CONFLICT,        content={            "message": "Conflict",            "detail": jsonable_encoder(exc.args[0] if exc.args else None),        },    )async def validation_error_handler(request: Request, exc: BadRequest) -> JSONResponse:    return JSONResponse(        status_code=status.HTTP_400_BAD_REQUEST,        content=ValidationErrorResponse(            message="Validation error", detail=exc.errors()  # type: ignore        ).model_dump(mode="json"),    )async def unauthorized_handler(request: Request, exc: Unauthorized) -> JSONResponse:    if exc.args:        logger.info(f"unauthorized: {exc}")    return JSONResponse(        status_code=status.HTTP_401_UNAUTHORIZED,        content={"message": "Unauthorized", "detail": None},        headers={"WWW-Authenticate": "Bearer"},    )async def permission_denied_handler(    request: Request, exc: PermissionDenied) -> JSONResponse:    return JSONResponse(        status_code=status.HTTP_403_FORBIDDEN,        content={            "message": "Permission denied",            "detail": jsonable_encoder(exc.args[0] if exc.args else None),        },    )
 |