Fastapi: [QUESTION] How to handle missing fields in model the same as the absence of the whole model

Created on 29 Aug 2019  路  3Comments  路  Source: tiangolo/fastapi

I want to handle missing fields in requests uniformly. If i don't specify some fields from model in request I get the list of errors with unfilled fields. However, when I don't send any fields at all I get different type of error which is that I didn't specify the model itself.

I've tried to override default exception handlers, but as far as I can see there is no way to override this behaviour. Is it possible to do? If not, can you elaborate on the alternative ways of doing this?

Sample code

from fastapi import FastAPI
from pydantic import BaseModel, ValidationError
from starlette.requests import Request
from starlette.testclient import TestClient


async def validation_exception_handler(request: Request, exc: ValidationError):
    print(exc.errors())


app = FastAPI()
app.add_exception_handler(ValidationError, validation_exception_handler)


class Item(BaseModel):
    uid: int
    name: str


@app.post("/pydantic/exception/model/")
async def pydantic_exception_model(item: Item):
    return {"item": item.dict()}


def test_exception_handler_pydantic_validationerror_model():
    with TestClient(app) as client:
        client.post("/pydantic/exception/model/")

        # If no fields are in the request, exception handler would print:
        #
        # [{'loc': ('body', 'item'), 'msg': 'field required', 'type': 'value_error.missing'}]
        #
        # Not able to get the fields and their required errors info from the `exc`

        client.post("/pydantic/exception/model/", json={"id": "str", "name": []})
        # But with some fields are missing and some are of the wrong type,
        # exception handler would print:
        #
        # [
        #  {'loc': ('body', 'item', 'uid'), 'msg': 'field required', 'type': 'value_error.missing'},
        #  {'loc': ('body', 'item', 'name'), 'msg': 'str type expected', 'type': 'type_error.str'}
        # ]
        # 
        # I can get the fields and errors info from the `exc`

question

All 3 comments

Hi, @levchik !

I do not know if the question is still relevant, but maybe it will be useful to others.

Fastapi has its own type of validation error, so to catch this error, you need to use something like in this example.

P.S In fact, @nsidnev got ahead of me in the decision while I was leaving for a bottle of beer. So basically this is his decision, you should say thanks to him :)

Example:


from fastapi import FastAPI
from fastapi.exceptions import RequestValidationError
from pydantic import BaseModel, ValidationError
from starlette.requests import Request
from starlette.responses import JSONResponse


app = FastAPI()


class Model(BaseModel):
    a: int


@app.exception_handler(ValidationError)
async def handler1(request: Request, exc: Exception):
    print("ValidationError")
    print(type(exc))
    return JSONResponse(str(exc))


@app.exception_handler(RequestValidationError)
async def handler2(request: Request, exc: Exception):
    print("RequestValidationError")
    print(type(exc))
    return JSONResponse(str(exc))


@app.exception_handler(Exception)
async def handler3(request: Request, exc: Exception):
    print("Exception")
    print(type(exc))
    return JSONResponse(str(exc))


@app.get("/")
async def route(m: Model) -> None:
    Model(a="asd")


@app.get("/run")
async def route2() -> None:
    raise RuntimeError("runtime error")

Thanks for the help here @Slyfoxy ! :clap: :bow:

@levchik does that solve your problem? May we close this issue?

@tiangolo yeah, sure, this issue is so old and not relevant now

Was this page helpful?
0 / 5 - 0 ratings