"""Mapper from exceptions to HTTP responses is defined here""" from typing import Callable, Type from fastapi import HTTPException from fastapi.responses import JSONResponse class ExceptionMapper: def __init__(self): self._known_exceptions: dict[Type, Callable[[Exception], JSONResponse]] = {} def register_simple(self, exception_type: Type, status_code: int, detail: str) -> None: self._known_exceptions[exception_type] = lambda _: JSONResponse( {"code": status_code, "detail": detail}, status_code=status_code ) def register_func(self, exception_type: Type, func: Callable[[Exception], JSONResponse]) -> None: self._known_exceptions[exception_type] = func def is_known(self, exc: Exception) -> bool: return type(exc) in self._known_exceptions or isinstance(exc, HTTPException) def apply(self, exc: Exception) -> JSONResponse: if (res := self.apply_if_known(exc)) is not None: return res return JSONResponse({"code": 500, "detail": "unhandled exception"}, status_code=500) def apply_if_known(self, exc: Exception) -> JSONResponse | None: if isinstance(exc, HTTPException): return JSONResponse({"code": exc.status_code, "detail": exc.detail}, status_code=exc.status_code) if (t := type(exc)) in self._known_exceptions: return self._known_exceptions[t](exc) return None