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"
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 😜
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_
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}} ヽ( ヅ )ノ