Fastapi: [QUESTION] how to return exception from validator schema?

Created on 7 Nov 2019  路  8Comments  路  Source: tiangolo/fastapi

i have schema with validator

@validator('number')
    def validate_phone(cls, v):
        if not validate_mobile_number(v):
            return {'msg': 'incorrect mobile number'}
        return v

when i send query with correct or incorrect number, i give response like:

{
  "detail": [
    {
      "loc": [
        "body",
        "user",
        "number"
      ],
      "msg": "expected string or bytes-like object",
      "type": "type_error"
    }
  ]
}

but where is my exception?

question

Most helpful comment

@foozzi
For example:

from fastapi import FastAPI
import pydantic

app = FastAPI()


class BadIdError(pydantic.PydanticValueError):
    msg_template = "You sent a wrong id!"


class MyUser(pydantic.BaseModel):
    id: int
    name: str

    @pydantic.validator("id")
    def validate_id(cls, v):
        if v + 1 != 10:
            raise BadIdError()
        return v


@app.post("/create")
async def create_user(_: MyUser):
    return {"status": "ok"}

image

All 8 comments

Hmm. May be should you add pre=True to validator decorator? It means what your validator will be called before default validators. You can see more about it in pydantic docs.

@prostomarkeloff i'm tried 'pre' and 'always' but it not working(

@foozzi

You aren't using a pydantic.validator properly -- you need to raise an error to cause a ValidationError, not return a dict. You probably don't need to set pre=True or always=True if you are just trying to validate if a string is a valid phone number, but you should only ever return a value that passes your validation. If the input fails validation, you need to raise an error.

If you are trying to get a custom error message, you may need to subclass pydantic.errors.PydanticValueError, for example, like this (taken out of pydantic.errors):

class StrictBoolError(PydanticValueError):
    msg_template = 'value is not a valid boolean'

and then raise that error in your validator.

You should probably also read the pydantic validator docs to make sure you understand what is going on.

If you are trying to change the
You have to raise a ValueError, TypeError, or AssertionError inside a validator in order to get an error output. You can read the pydantic docs about validators for more details.

@dmontagu Thank you!
but i'm tried this:

class UserBase(BaseModel):
    number: int

    @validator('number')
    def validate_phone(cls, v):
        print(validate_mobile_number(v))
        if validate_mobile_number(v) is False:
            raise TypeError(f'test')
        return v

and nothing changed...

i'm read docs for pydantic for validators

Like I said, if you want to change the error message, you have to subclass PydanticValueError (or PydanticTypeError or similar).

@foozzi
For example:

from fastapi import FastAPI
import pydantic

app = FastAPI()


class BadIdError(pydantic.PydanticValueError):
    msg_template = "You sent a wrong id!"


class MyUser(pydantic.BaseModel):
    id: int
    name: str

    @pydantic.validator("id")
    def validate_id(cls, v):
        if v + 1 != 10:
            raise BadIdError()
        return v


@app.post("/create")
async def create_user(_: MyUser):
    return {"status": "ok"}

image

Thanks a lot for the help @dmontagu and @prostomarkeloff ! :bowing_man: :clap:

Does that solve your use case @foozzi ? Wanna close this issue?

Thanks a lot for the help @dmontagu and @prostomarkeloff ! bowing_man clap

Does that solve your use case @foozzi ? Wanna close this issue?

yep! thx you all

Was this page helpful?
0 / 5 - 0 ratings