Pydantic: Show param values in validation error messages

Created on 27 Aug 2019  Â·  7Comments  Â·  Source: samuelcolvin/pydantic

Feature Request

This originates from https://github.com/tiangolo/fastapi/issues/473:

The error messages created by the parameter validation are like "msg": "value is not a valid integer".

It would be helpful for debugging if they contained the actual value of that parmeter: "msg": f"value '{param}' is not a valid integer" -> "msg": "value 'spam' is not a valid integer"

feature request

Most helpful comment

First of all, absolutely love the package, thanks for making something so magical @Pydantic crew.

This was doing my absolute head in as i'm working with some incredibly complex nested dataclasses, so you can patch the libraries' files for a quick fix until it gets patched in:


Version: pydantic==1.6.1

validators.py
_Modify the error call for the validator you want to change so that is passes the value, v_

raise errors.AnyStrMaxLengthError(limit_value=max_length)

becomes...

raise errors.AnyStrMaxLengthError(value=v, limit_value=max_length)

errors.py
_Follow the function call and edit the __init__ function so it takes the value and adds it to the Super() init_

class AnyStrMaxLengthError(PydanticValueError):
    code = 'any_str.max_length'
    msg_template = 'ensure this value has at most {limit_value} characters'

    # def __init__(self, *, limit_value: int) -> None:
    #   super().__init__(limit_value=limit_value)

    def __init__(self, *, value, limit_value: int) -> None:
        super().__init__(value=value, limit_value=limit_value)

It should now show up inside the ctx value in e.errors()

{'ctx': {'value': 'abcdefghijklmnopqrs', 'limit_value': 15} ヽ( ヅ )ノ


Edit: You can load anything in to the super() call. So for max/min length validation i've found it useful to also pass through the string length

super().__init__(value=value, vlen=len(value), limit_value=limit_value)

{'ctx': {'value': 'abcdefghijklmnopqrs', 'vlen': 19, 'limit_value': 15}} ヽ( ヅ )ノ

All 7 comments

I disagree. What if the value is a string of 5000 characters? Should we show the entire thing in the error message.

However I think we could do with improving the data available about errors, for example we should make sure the provided value is always available in ctx and that all error types are unique, so completely custom logic and error message translations work properly.

If the string is too long, we might abbreviate it like this?

str_val = str(value)
if len(str_val) > 15:
    str_val = f'{str_val[:8]}...{str_val[-4:]}'

But I would be hapy with anything that improves the error message (and thus, debugging). :)

debugging would be fixed by adding the original value to ctx which would then be shown in the str() method of ValidationError and therefore python's standard error printing.

Can I somehow help with this?

Mentioning #1938 for another use-case/problem that arises from this issue.

First of all, absolutely love the package, thanks for making something so magical @Pydantic crew.

This was doing my absolute head in as i'm working with some incredibly complex nested dataclasses, so you can patch the libraries' files for a quick fix until it gets patched in:


Version: pydantic==1.6.1

validators.py
_Modify the error call for the validator you want to change so that is passes the value, v_

raise errors.AnyStrMaxLengthError(limit_value=max_length)

becomes...

raise errors.AnyStrMaxLengthError(value=v, limit_value=max_length)

errors.py
_Follow the function call and edit the __init__ function so it takes the value and adds it to the Super() init_

class AnyStrMaxLengthError(PydanticValueError):
    code = 'any_str.max_length'
    msg_template = 'ensure this value has at most {limit_value} characters'

    # def __init__(self, *, limit_value: int) -> None:
    #   super().__init__(limit_value=limit_value)

    def __init__(self, *, value, limit_value: int) -> None:
        super().__init__(value=value, limit_value=limit_value)

It should now show up inside the ctx value in e.errors()

{'ctx': {'value': 'abcdefghijklmnopqrs', 'limit_value': 15} ヽ( ヅ )ノ


Edit: You can load anything in to the super() call. So for max/min length validation i've found it useful to also pass through the string length

super().__init__(value=value, vlen=len(value), limit_value=limit_value)

{'ctx': {'value': 'abcdefghijklmnopqrs', 'vlen': 19, 'limit_value': 15}} ヽ( ヅ )ノ

@Fireclunge sounds like we got a PR on our hands 😜

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bradodarb picture bradodarb  Â·  22Comments

chopraaa picture chopraaa  Â·  18Comments

jasonkuhrt picture jasonkuhrt  Â·  19Comments

koxudaxi picture koxudaxi  Â·  25Comments

Gaunt picture Gaunt  Â·  19Comments