Squashed 'pm/' content from commit 91f3271
git-subtree-dir: pm git-subtree-split: 91f3271d866fa8ee471cfb6793e334b83e6d2b6e
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
"""PM error envelope — same contract as the ERP: {"error": {code, message, field}}."""
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
|
||||
class AppError(Exception):
|
||||
status_code = 400
|
||||
code = "BAD_REQUEST"
|
||||
|
||||
def __init__(self, message: str, field: str | None = None, code: str | None = None):
|
||||
super().__init__(message)
|
||||
self.message = message
|
||||
self.field = field
|
||||
if code:
|
||||
self.code = code
|
||||
|
||||
@property
|
||||
def body(self) -> dict:
|
||||
error = {"code": self.code, "message": self.message}
|
||||
if self.field is not None:
|
||||
error["field"] = self.field
|
||||
return {"error": error}
|
||||
|
||||
|
||||
class AuthError(AppError):
|
||||
status_code, code = 401, "UNAUTHORIZED"
|
||||
|
||||
|
||||
class ValidationError(AppError):
|
||||
status_code, code = 400, "VALIDATION_ERROR"
|
||||
|
||||
|
||||
class ForbiddenError(AppError):
|
||||
status_code, code = 403, "FORBIDDEN"
|
||||
|
||||
|
||||
class NotFoundError(AppError):
|
||||
status_code, code = 404, "NOT_FOUND"
|
||||
|
||||
|
||||
class ConflictError(AppError):
|
||||
status_code, code = 409, "CONFLICT"
|
||||
|
||||
|
||||
class UpstreamError(AppError):
|
||||
"""Upstream service unreachable / errored."""
|
||||
status_code, code = 503, "UPSTREAM_UNAVAILABLE"
|
||||
|
||||
|
||||
def install_error_handlers(app: FastAPI) -> None:
|
||||
@app.exception_handler(AppError)
|
||||
async def _app_error(_: Request, exc: AppError) -> JSONResponse:
|
||||
return JSONResponse(status_code=exc.status_code, content=exc.body)
|
||||
Reference in New Issue
Block a user