Implement Monlet MVP stack and UI updates
This commit is contained in:
54
server/monlet_server/errors.py
Normal file
54
server/monlet_server/errors.py
Normal file
@@ -0,0 +1,54 @@
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.exceptions import RequestValidationError
|
||||
from fastapi.responses import JSONResponse
|
||||
from starlette.exceptions import HTTPException as StarletteHTTPException
|
||||
|
||||
from .logging_config import get_logger, request_id_var
|
||||
from .schemas import ErrorBody, ErrorCode, ErrorResponse
|
||||
|
||||
log = get_logger("monlet.errors")
|
||||
|
||||
|
||||
def _request_id(request: Request) -> str:
|
||||
rid = getattr(request.state, "request_id", None)
|
||||
if rid is None:
|
||||
rid = request_id_var.get() or ""
|
||||
return rid
|
||||
|
||||
|
||||
def error_response(
|
||||
request: Request, status_code: int, code: ErrorCode, message: str
|
||||
) -> JSONResponse:
|
||||
body = ErrorResponse(
|
||||
error=ErrorBody(code=code, message=message, request_id=_request_id(request))
|
||||
)
|
||||
return JSONResponse(status_code=status_code, content=body.model_dump())
|
||||
|
||||
|
||||
_STATUS_TO_CODE: dict[int, ErrorCode] = {
|
||||
400: "validation",
|
||||
401: "unauthorized",
|
||||
404: "not_found",
|
||||
413: "payload_too_large",
|
||||
429: "rate_limited",
|
||||
500: "internal",
|
||||
503: "not_ready",
|
||||
}
|
||||
|
||||
|
||||
def install_error_handlers(app: FastAPI) -> None:
|
||||
@app.exception_handler(RequestValidationError)
|
||||
async def _validation(request: Request, exc: RequestValidationError):
|
||||
message = "request validation failed"
|
||||
return error_response(request, 400, "validation", message)
|
||||
|
||||
@app.exception_handler(StarletteHTTPException)
|
||||
async def _http(request: Request, exc: StarletteHTTPException):
|
||||
code = _STATUS_TO_CODE.get(exc.status_code, "internal")
|
||||
msg = exc.detail if isinstance(exc.detail, str) else code
|
||||
return error_response(request, exc.status_code, code, msg)
|
||||
|
||||
@app.exception_handler(Exception)
|
||||
async def _unhandled(request: Request, exc: Exception):
|
||||
log.exception("unhandled_exception", error=type(exc).__name__)
|
||||
return error_response(request, 500, "internal", "internal server error")
|
||||
Reference in New Issue
Block a user