-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Currently if you have a deeply nested data structure, when a validation error occurs then a user sees a deeply nested exception that displays several exceptions and their tracebacks, which isn't particularly easy to see what's incorrect. It would be useful for ValidationError to get a flatten method that converts the many nested exceptions into something more readable.
I put this together really quickly (so it might not be ideal yet), flatten could be _convert_validation_error?
import typing
from validobj import errors
import validobj.validation
T = typing.TypeVar("T")
class ValidationError(Exception):
pass
def _convert_validation_error(fname: str, ve: errors.ValidationError) -> ValidationError:
locs = []
msg = []
e = ve
while e is not None:
if isinstance(e, errors.WrongFieldError):
locs.append(f".{e.wrong_field}")
elif isinstance(e, errors.WrongListItemError):
locs.append(f"[{e.wrong_index}]")
else:
msg.append(str(e))
e = e.__cause__
loc = "".join(locs)
if loc.startswith("."):
loc = loc[1:]
vmsg = f"{fname}: {loc}:\n {'\n '.join(msg)}"
return ValidationError(vmsg)
def parse_input(value: typing.Any, spec: typing.Type[T], fname: str) -> T:
try:
return validobj.validation.parse_input(value, spec)
except errors.ValidationError as ve:
raise _convert_validation_error(fname, ve) from NoneThe idea is you'd get a shorter more useful error message like this:
util.ValidationError: downloaded.yml: functions.downloaded_fn:
Expecting value to be a dict, compatible with 'FunctionData', not 'NoneType'
It would be nice if something like this was in the library instead of needing to duplicate the same logic across a bunch of different programs. In particular, this would be useful for CLIs that read configuration files using validobj.