mirror of https://github.com/tiangolo/fastapi.git
🐛 Fix issue with exotic pydantic error serialization (#748)
This commit is contained in:
parent
cc4c13e4ae
commit
19c77e35bd
|
|
@ -1,3 +1,4 @@
|
||||||
|
from fastapi.encoders import jsonable_encoder
|
||||||
from fastapi.exceptions import RequestValidationError
|
from fastapi.exceptions import RequestValidationError
|
||||||
from starlette.exceptions import HTTPException
|
from starlette.exceptions import HTTPException
|
||||||
from starlette.requests import Request
|
from starlette.requests import Request
|
||||||
|
|
@ -19,5 +20,6 @@ async def request_validation_exception_handler(
|
||||||
request: Request, exc: RequestValidationError
|
request: Request, exc: RequestValidationError
|
||||||
) -> JSONResponse:
|
) -> JSONResponse:
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
status_code=HTTP_422_UNPROCESSABLE_ENTITY, content={"detail": exc.errors()}
|
status_code=HTTP_422_UNPROCESSABLE_ENTITY,
|
||||||
|
content={"detail": jsonable_encoder(exc.errors())},
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
|
from decimal import Decimal
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel, condecimal
|
||||||
from starlette.testclient import TestClient
|
from starlette.testclient import TestClient
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
@ -9,7 +10,7 @@ app = FastAPI()
|
||||||
|
|
||||||
class Item(BaseModel):
|
class Item(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
age: int
|
age: condecimal(gt=Decimal(0.0))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/items/")
|
@app.post("/items/")
|
||||||
|
|
@ -67,7 +68,7 @@ openapi_schema = {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"name": {"title": "Name", "type": "string"},
|
"name": {"title": "Name", "type": "string"},
|
||||||
"age": {"title": "Age", "type": "integer"},
|
"age": {"title": "Age", "exclusiveMinimum": 0.0, "type": "number"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"ValidationError": {
|
"ValidationError": {
|
||||||
|
|
@ -99,6 +100,17 @@ openapi_schema = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
single_error = {
|
||||||
|
"detail": [
|
||||||
|
{
|
||||||
|
"ctx": {"limit_value": 0.0},
|
||||||
|
"loc": ["body", "item", 0, "age"],
|
||||||
|
"msg": "ensure this value is greater than 0",
|
||||||
|
"type": "value_error.number.not_gt",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
multiple_errors = {
|
multiple_errors = {
|
||||||
"detail": [
|
"detail": [
|
||||||
{
|
{
|
||||||
|
|
@ -108,8 +120,8 @@ multiple_errors = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"loc": ["body", "item", 0, "age"],
|
"loc": ["body", "item", 0, "age"],
|
||||||
"msg": "value is not a valid integer",
|
"msg": "value is not a valid decimal",
|
||||||
"type": "type_error.integer",
|
"type": "type_error.decimal",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"loc": ["body", "item", 1, "name"],
|
"loc": ["body", "item", 1, "name"],
|
||||||
|
|
@ -118,8 +130,8 @@ multiple_errors = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"loc": ["body", "item", 1, "age"],
|
"loc": ["body", "item", 1, "age"],
|
||||||
"msg": "value is not a valid integer",
|
"msg": "value is not a valid decimal",
|
||||||
"type": "type_error.integer",
|
"type": "type_error.decimal",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +149,13 @@ def test_put_correct_body():
|
||||||
assert response.json() == {"item": [{"name": "Foo", "age": 5}]}
|
assert response.json() == {"item": [{"name": "Foo", "age": 5}]}
|
||||||
|
|
||||||
|
|
||||||
def test_put_incorrect_body():
|
def test_jsonable_encoder_requiring_error():
|
||||||
|
response = client.post("/items/", json=[{"name": "Foo", "age": -1.0}])
|
||||||
|
assert response.status_code == 422
|
||||||
|
assert response.json() == single_error
|
||||||
|
|
||||||
|
|
||||||
|
def test_put_incorrect_body_multiple():
|
||||||
response = client.post("/items/", json=[{"age": "five"}, {"age": "six"}])
|
response = client.post("/items/", json=[{"age": "five"}, {"age": "six"}])
|
||||||
assert response.status_code == 422
|
assert response.status_code == 422
|
||||||
assert response.json() == multiple_errors
|
assert response.json() == multiple_errors
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue