Skip to content

Provide method to get more concise error message #12

@virtuald

Description

@virtuald

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 None

The 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions