That looks like a JSON response and Pydantic by itself does not give out a JSON response for ValidationError
's. It should just be a regular raise
-d Exception
like this:
In [2]: from pydantic import BaseModel, constr
In [3]: class Credentials(BaseModel):
...: password: constr(min_length=8)
...:
In [4]: Credentials(password="xyz")
---------------------------------------------------------------------------
ValidationError Traceback (most recent call last)
Input In [4], in <cell line: 1>()
----> 1 Credentials(password="xyz")
...
ValidationError: 1 validation error for Credentials
password
ensure this value has at least 8 characters (type=value_error.any_str.min_length; limit_value=8)
I think you are using FastAPI (which has Pydantic integration) and this JSON response is actually FastAPI's built-in error response when the request has ValidationError
's, as described in the FastAPI docs on Handling Errors. I can replicate a similar error format with this example:
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from pydantic import BaseModel, constr
class Credentials(BaseModel):
password: constr(min_length=8)
app = FastAPI()
@app.post("/login")
async def login(credentials: Credentials):
print(credentials) # This is just as an example!
return JSONResponse(status_code=200)
$ curl -s --header "Content-Type: application/json" --request POST --data '{"password":"xyz"}' http://localhost:8000/login | jq
{
"detail": [
{
"loc": [
"body",
"password"
],
"msg": "ensure this value has at least 8 characters",
"type": "value_error.any_str.min_length",
"ctx": {
"limit_value": 8
}
}
]
}
To change the response body, check the FastAPI docs on Use the RequestValidationError body that shows you can access the default detail
list of errors, which you can then edit or copy over to a customized details list, and then set it as the content
of the JSON error response.
from fastapi import FastAPI, Request, status
from fastapi.encoders import jsonable_encoder
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
from pydantic import BaseModel, constr
class Credentials(BaseModel):
password: constr(min_length=8)
app = FastAPI()
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
# Get the original 'detail' list of errors
details = exc.errors()
modified_details = []
# Replace 'msg' with 'message' for each error
for error in details:
modified_details.append(
{
"loc": error["loc"],
"message": error["msg"],
"type": error["type"],
}
)
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content=jsonable_encoder({"detail": modified_details}),
)
@app.post("/login")
async def login(credentials: Credentials):
print(credentials) # Just as an example!
return JSONResponse(status_code=200)
$ curl -s --header "Content-Type: application/json" --request POST --data '{"password":"xyz"}' http://localhost:8000/login | jq
{
"detail": [
{
"loc": [
"body",
"password"
],
"message": "ensure this value has at least 8 characters",
"type": "value_error.any_str.min_length"
}
]
}
Of course, you can also simply just define your own custom content
and JSONResponse
.