Version 0.4.0
All checks were successful
Run linters on applied template / Python 3.13 lint and build (push) Successful in 1m40s
All checks were successful
Run linters on applied template / Python 3.13 lint and build (push) Successful in 1m40s
Changes: - put ObservabilityMiddleware before ExceptionHandlerMiddleware to avoid repetative code - add application startup and last metrics update metrics along with CPU usage metric and threads count - move host and port to new uvicorn section at config along with new reload and forwarded_allow_ips - add request_id and remove trace_id/span_id generation if tracing is disabled - move logging logic from utils to observability - pass trace_id/span_id in HEX form
This commit is contained in:
7
{{project_slug}}/exceptions/auth.py.jinja
Normal file
7
{{project_slug}}/exceptions/auth.py.jinja
Normal file
@@ -0,0 +1,7 @@
|
||||
"""Authentication exceptions are located here."""
|
||||
|
||||
from {{project_slug}}.exceptions.base import {{ProjectName}}Error
|
||||
|
||||
|
||||
class NotAuthorizedError({{ProjectName}}Error):
|
||||
"""Exception to raise when user token is not set, but is required."""
|
||||
@@ -2,23 +2,37 @@
|
||||
|
||||
from typing import Callable, Type
|
||||
|
||||
from fastapi import HTTPException
|
||||
from fastapi.responses import JSONResponse
|
||||
from starlette.exceptions import HTTPException
|
||||
|
||||
|
||||
class ExceptionMapper:
|
||||
"""Maps exceptions to `JSONResponse` for FastAPI error handling."""
|
||||
|
||||
def __init__(self):
|
||||
self._known_exceptions: dict[Type, Callable[[Exception], JSONResponse]] = {}
|
||||
|
||||
def register_simple(self, exception_type: Type, status_code: int, detail: str) -> None:
|
||||
def register_simple(self, exception_type: Type, status_code: int, details: str) -> None:
|
||||
"""Register simple response handler with setting status_code and details."""
|
||||
self._known_exceptions[exception_type] = lambda _: JSONResponse(
|
||||
{"code": status_code, "detail": detail}, status_code=status_code
|
||||
{"error": f"{exception_type.__module__}.{exception_type.__qualname__}", "details": details},
|
||||
status_code=status_code,
|
||||
)
|
||||
|
||||
def register_func(self, exception_type: Type, func: Callable[[Exception], JSONResponse]) -> None:
|
||||
"""Register complex response handler by passing function."""
|
||||
self._known_exceptions[exception_type] = func
|
||||
|
||||
def get_status_code(self, exc: Exception) -> int:
|
||||
"""Get status code of preparing response."""
|
||||
if isinstance(exc, HTTPException):
|
||||
return exc.status_code
|
||||
if type(exc) in self._known_exceptions:
|
||||
return self._known_exceptions[type(exc)](exc).status_code
|
||||
return 500
|
||||
|
||||
def is_known(self, exc: Exception) -> bool:
|
||||
|
||||
return type(exc) in self._known_exceptions or isinstance(exc, HTTPException)
|
||||
|
||||
def apply(self, exc: Exception) -> JSONResponse:
|
||||
|
||||
Reference in New Issue
Block a user