"""Domain exception → HTTP response mapping. This module provides a single exception handler that converts domain-layer exceptions into structured JSON responses, keeping the service layer free from FastAPI's ``HTTPException``. """ from fastapi import Request from fastapi.responses import JSONResponse from app.domain.exceptions import ( AuthorizationError, DomainException, DuplicateEntityError, EntityNotFoundError, InvalidOperationError, InvalidTransitionError, ) EXCEPTION_STATUS_MAP: dict[type[DomainException], int] = { EntityNotFoundError: 404, DuplicateEntityError: 409, InvalidTransitionError: 400, InvalidOperationError: 400, AuthorizationError: 403, } async def domain_exception_handler( request: Request, exc: DomainException, ) -> JSONResponse: """Convert a :class:`DomainException` into a JSON error response.""" status_code = EXCEPTION_STATUS_MAP.get(type(exc), 400) content: dict = {"detail": exc.message, "code": exc.code} if isinstance(exc, InvalidTransitionError): content["current_state"] = exc.current_state content["target_state"] = exc.target_state content["valid_transitions"] = exc.valid_transitions return JSONResponse(status_code=status_code, content=content)