¿Cómo personalizar la respuesta de error en FastAPI?
Tengo el siguiente backend FastAPI:
from fastapi import FastAPI
app = FastAPI
class Demo(BaseModel):
content: str = None
@app.post("/demo")
async def demoFunc(d:Demo):
return d.content
El problema es que cuando envío una solicitud a esta API con datos adicionales como:
data = {"content":"some text here"}aaaa
o
data = {"content":"some text here"aaaaaa}
resp = requests.post(url, json=data)
arroja un error con código de estado 422 unprocessable entity
de error con datos reales ("algo de texto aquí") y adicionales ("aaaaa") en el campo de retorno en caso de data = {"content":"some text here"}aaaa
:
{
"detail": [
{
"loc": [
"body",
47
],
"msg": "Extra data: line 4 column 2 (char 47)",
"type": "value_error.jsondecode",
"ctx": {
"msg": "Extra data",
"doc": "{\n \"content\": \"some text here\"}aaaaa",
"pos": 47,
"lineno": 4,
"colno": 2
}
}
]
}
Intenté poner la línea app=FastAPI()
en un bloque try-catch, sin embargo, no funciona. ¿Hay alguna manera de poder manejar este problema con una respuesta propia en lugar de la respuesta automática mencionada anteriormente? Algo como esto:
{"error": {"message": "Invalid JSON body"},
"status": 0}
Está pasando un JSON no válido y, por lo tanto, el servidor responde correctamente con el 422 Unprocessable Entity
error. Su cliente de prueba no debería poder ejecutarse en absoluto sin generar un invalid syntax
error. Entonces, supongo que publicó la solicitud a través de los documentos automáticos interactivos proporcionados por Swagger UI en /docs
y recibió el error 422 relevante.
Si lo que realmente desea es manejar el error, para personalizar el error o algo así, puede anular el controlador de excepción de validación de solicitud, como se describe en la documentación (consulte esta discusión , así como esta respuesta y esta respuesta que demuestra cómo personalizar RequestValidationError
solo para rutas específicas).
Ejemplo de trabajo:
from fastapi import FastAPI, Body, Request, status
from fastapi.encoders import jsonable_encoder
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
from pydantic import BaseModel
app = FastAPI()
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content=jsonable_encoder({"detail": exc.errors(), # optionally include the errors
"body": exc.body,
"custom msg": {"Your error message"}}),
)
class Demo(BaseModel):
content: str = None
@app.post("/demo")
async def some_func(d: Demo):
return d.content
O también puedes devolver un PlainTextResponse
mensaje personalizado:
from fastapi.responses import PlainTextResponse
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
return PlainTextResponse(str(exc), status_code=422)