File size: 1,313 Bytes
d2d1903 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | """
infra.api.errors — the API error model.
One exception type, ``ApiError``, carrying a machine-readable ``code``, a
human ``message`` and the HTTP ``status`` it maps to. Handlers raise it; the
FastAPI shell (app.py) catches it and renders a consistent JSON body:
{"error": {"code": "...", "message": "..."}}
Pure module — no fastapi dependency, so handlers stay testable without a
web server.
"""
from __future__ import annotations
class ApiError(Exception):
"""A handler-level error with a stable code and an HTTP status."""
def __init__(self, code: str, message: str, status: int = 400):
super().__init__(message)
self.code = code
self.message = message
self.status = status
def to_dict(self) -> dict:
return {"error": {"code": self.code, "message": self.message}}
# --- common errors, as small factories so codes/statuses stay consistent ---
def bad_request(message: str) -> ApiError:
return ApiError("bad_request", message, status=400)
def not_found(message: str) -> ApiError:
return ApiError("not_found", message, status=404)
def conflict(message: str) -> ApiError:
return ApiError("conflict", message, status=409)
def unprocessable(message: str) -> ApiError:
return ApiError("unprocessable", message, status=422)
|