Add exception handler to make flat error responses.
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
from fastapi import FastAPI, HTTPException, status
|
from fastapi import FastAPI, HTTPException, status
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
from starlette.requests import Request
|
||||||
from typing import List, Optional, Union, Dict, Any, Tuple
|
from typing import List, Optional, Union, Dict, Any, Tuple
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
import os
|
import os
|
||||||
@@ -31,6 +33,41 @@ app = FastAPI(
|
|||||||
lifespan=lifespan
|
lifespan=lifespan
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@app.exception_handler(HTTPException)
|
||||||
|
async def http_exception_handler(request: Request, exc: HTTPException):
|
||||||
|
"""
|
||||||
|
Handles FastAPI's HTTPException to enforce a consistent, flat error
|
||||||
|
response structure (removing the default 'detail' wrapping).
|
||||||
|
|
||||||
|
The handler expects 'exc.detail' to be a dictionary containing the
|
||||||
|
desired error structure with the key 'error' (e.g., {"error": {...}}).
|
||||||
|
|
||||||
|
:param request: The incoming request object.
|
||||||
|
:param exc: The HTTPException instance raised (e.g., in validate_single_or_batch).
|
||||||
|
:return: A JSONResponse object with the custom error body and the correct status code.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Determine the content to be returned in the response body
|
||||||
|
if isinstance(exc.detail, dict) and "error" in exc.detail:
|
||||||
|
# If the detail matches the expected custom format (e.g., {"error": {...}}),
|
||||||
|
# use the entire dictionary as the response content.
|
||||||
|
response_body = exc.detail
|
||||||
|
else:
|
||||||
|
# Fallback for unexpected or standard FastAPI error formats (e.g., detail is a string).
|
||||||
|
# Ensures the response always adheres to the expected structure.
|
||||||
|
response_body = {
|
||||||
|
"error": {
|
||||||
|
"code": "GENERIC_ERROR",
|
||||||
|
"message": str(exc.detail),
|
||||||
|
"details": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=exc.status_code,
|
||||||
|
content=response_body
|
||||||
|
)
|
||||||
|
|
||||||
# ==================== Endpoints ====================
|
# ==================== Endpoints ====================
|
||||||
@app.get("/health")
|
@app.get("/health")
|
||||||
async def health_check():
|
async def health_check():
|
||||||
|
|||||||
Reference in New Issue
Block a user