==========================
Handling Validation Errors
==========================

.. currentmodule:: jsonschema.exceptions

When an invalid instance is encountered, a `ValidationError` will be
raised or returned, depending on which method or function is used.

.. autoexception:: ValidationError
    :noindex:

    The information carried by an error roughly breaks down into:

    ===============  =================  ========================
     What Happened   Why Did It Happen  What Was Being Validated
    ===============  =================  ========================
    `message`        `context`          `instance`

                     `cause`            `json_path`

                                        `path`

                                        `schema`

                                        `schema_path`

                                        `validator`

                                        `validator_value`
    ===============  =================  ========================


    .. attribute:: message

        A human readable message explaining the error.

    .. attribute:: validator

        The name of the failed `keyword
        <https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-structural>`_.

    .. attribute:: validator_value

        The associated value for the failed keyword in the schema.

    .. attribute:: schema

        The full schema that this error came from. This is potentially a
        subschema from within the schema that was passed in originally,
        or even an entirely different schema if a :kw:`$ref` was
        followed.

    .. attribute:: relative_schema_path

        A `collections.deque` containing the path to the failed keyword
        within the schema.

    .. attribute:: absolute_schema_path

        A `collections.deque` containing the path to the failed
        keyword within the schema, but always relative to the
        *original* schema as opposed to any subschema (i.e. the one
        originally passed into a validator class, *not* `schema`\).

    .. attribute:: schema_path

        Same as `relative_schema_path`.

    .. attribute:: relative_path

        A `collections.deque` containing the path to the
        offending element within the instance. The deque can be empty if
        the error happened at the root of the instance.

    .. attribute:: absolute_path

        A `collections.deque` containing the path to the
        offending element within the instance. The absolute path
        is always relative to the *original* instance that was
        validated (i.e. the one passed into a validation method, *not*
        `instance`\). The deque can be empty if the error happened
        at the root of the instance.

    .. attribute:: json_path

        A `JSON path <https://goessner.net/articles/JsonPath/index.html>`_
        to the offending element within the instance.

    .. attribute:: path

        Same as `relative_path`.

    .. attribute:: instance

        The instance that was being validated. This will differ from
        the instance originally passed into ``validate`` if the
        validator object was in the process of validating a (possibly
        nested) element within the top-level instance. The path within
        the top-level instance (i.e. `ValidationError.path`) could
        be used to find this object, but it is provided for convenience.

    .. attribute:: context

        If the error was caused by errors in subschemas, the list of errors
        from the subschemas will be available on this property. The
        `schema_path` and `path` of these errors will be relative
        to the parent error.

    .. attribute:: cause

        If the error was caused by a *non*-validation error, the
        exception object will be here. Currently this is only used
        for the exception raised by a failed format checker in
        `jsonschema.FormatChecker.check`.

    .. attribute:: parent

        A validation error which this error is the `context` of.
        ``None`` if there wasn't one.


In case an invalid schema itself is encountered, a `SchemaError` is
raised.

.. autoexception:: SchemaError
    :noindex:

    The same attributes are present as for `ValidationError`\s.


These attributes can be clarified with a short example:

.. testcode::

    schema = {
        "items": {
            "anyOf": [
                {"type": "string", "maxLength": 2},
                {"type": "integer", "minimum": 5}
            ]
        }
    }
    instance = [{}, 3, "foo"]
    v = Draft202012Validator(schema)
    errors = sorted(v.iter_errors(instance), key=lambda e: e.path)

The error messages in this situation are not very helpful on their own.

.. testcode::

    for error in errors:
        print(error.message)

outputs:

.. testoutput::

    {} is not valid under any of the given schemas
    3 is not valid under any of the given schemas
    'foo' is not valid under any of the given schemas

If we look at `ValidationError.path` on each of the errors, we can find
out which elements in the instance correspond to each of the errors. In
this example, `ValidationError.path` will have only one element, which
will be the index in our list.

.. testcode::

    for error in errors:
        print(list(error.path))

.. testoutput::

    [0]
    [1]
    [2]

Since our schema contained nested subschemas, it can be helpful to look at
the specific part of the instance and subschema that caused each of the errors.
This can be seen with the `ValidationError.instance` and
`ValidationError.schema` attributes.

With keywords like :kw:`anyOf`, the `ValidationError.context`
attribute can be used to see the sub-errors which caused the failure. Since
these errors actually came from two separate subschemas, it can be helpful to
look at the `ValidationError.schema_path` attribute as well to see where
exactly in the schema each of these errors come from. In the case of sub-errors
from the `ValidationError.context` attribute, this path will be relative
to the `ValidationError.schema_path` of the parent error.

.. testcode::

    for error in errors:
        for suberror in sorted(error.context, key=lambda e: e.schema_path):
            print(list(suberror.schema_path), suberror.message, sep=", ")

.. testoutput::

    [0, 'type'], {} is not of type 'string'
    [1, 'type'], {} is not of type 'integer'
    [0, 'type'], 3 is not of type 'string'
    [1, 'minimum'], 3 is less than the minimum of 5
    [0, 'maxLength'], 'foo' is too long
    [1, 'type'], 'foo' is not of type 'integer'

The string representation of an error combines some of these attributes for
easier debugging.

.. testcode::

    print(errors[1])

.. testoutput::

    3 is not valid under any of the given schemas

    Failed validating 'anyOf' in schema['items']:
        {'anyOf': [{'type': 'string', 'maxLength': 2},
                   {'type': 'integer', 'minimum': 5}]}

    On instance[1]:
        3


ErrorTrees
----------

If you want to programmatically query which validation keywords
failed when validating a given instance, you may want to do so using
`jsonschema.exceptions.ErrorTree` objects.

.. autoclass:: jsonschema.exceptions.ErrorTree
    :noindex:
    :members:
    :special-members:
    :exclude-members: __dict__,__weakref__

    .. attribute:: errors

        The mapping of validation keywords to the error objects (usually `jsonschema.exceptions.ValidationError`\s) at this level of the tree.

Consider the following example:

.. testcode::

    schema = {
        "type" : "array",
        "items" : {"type" : "number", "enum" : [1, 2, 3]},
        "minItems" : 3,
    }
    instance = ["spam", 2]

For clarity's sake, the given instance has three errors under this schema:

.. testcode::

    v = Draft202012Validator(schema)
    for error in sorted(v.iter_errors(["spam", 2]), key=str):
        print(error.message)

.. testoutput::

    'spam' is not of type 'number'
    'spam' is not one of [1, 2, 3]
    ['spam', 2] is too short

Let's construct an `jsonschema.exceptions.ErrorTree` so that we
can query the errors a bit more easily than by just iterating over the
error objects.

.. testcode::

    from jsonschema.exceptions import ErrorTree
    tree = ErrorTree(v.iter_errors(instance))

As you can see, `jsonschema.exceptions.ErrorTree` takes an iterable of `ValidationError`\s when constructing a tree so you can directly pass it the return value of a validator's `jsonschema.protocols.Validator.iter_errors` method.

`ErrorTree`\s support a number of useful operations. The first one we
might want to perform is to check whether a given element in our instance
failed validation. We do so using the :keyword:`in` operator:

.. doctest::

    >>> 0 in tree
    True

    >>> 1 in tree
    False

The interpretation here is that the 0th index into the instance (``"spam"``)
did have an error (in fact it had 2), while the 1th index (``2``) did not (i.e.
it was valid).

If we want to see which errors a child had, we index into the tree and look at
the `ErrorTree.errors` attribute.

.. doctest::

    >>> sorted(tree[0].errors)
    ['enum', 'type']

Here we see that the :kw:`enum` and :kw:`type` keywords failed for
index ``0``. In fact `ErrorTree.errors` is a dict, whose values are the
`ValidationError`\s, so we can get at those directly if we want them.

.. doctest::

    >>> print(tree[0].errors["type"].message)
    'spam' is not of type 'number'

Of course this means that if we want to know if a given validation
keyword failed for a given index, we check for its presence in
`ErrorTree.errors`:

.. doctest::

    >>> "enum" in tree[0].errors
    True

    >>> "minimum" in tree[0].errors
    False

Finally, if you were paying close enough attention, you'll notice that
we haven't seen our :kw:`minItems` error appear anywhere yet. This is
because :kw:`minItems` is an error that applies globally to the instance
itself. So it appears in the root node of the tree.

.. doctest::

    >>> "minItems" in tree.errors
    True

That's all you need to know to use error trees.

To summarize, each tree contains child trees that can be accessed by
indexing the tree to get the corresponding child tree for a given
index into the instance. Each tree and child has a `ErrorTree.errors`
attribute, a dict, that maps the failed validation keyword to the
corresponding validation error.


best_match and relevance
------------------------

The `best_match` function is a simple but useful function for attempting
to guess the most relevant error in a given bunch.

.. doctest::

        >>> from jsonschema import Draft202012Validator
        >>> from jsonschema.exceptions import best_match

        >>> schema = {
        ...     "type": "array",
        ...     "minItems": 3,
        ... }
        >>> print(best_match(Draft202012Validator(schema).iter_errors(11)).message)
        11 is not of type 'array'


.. autofunction:: best_match
    :noindex:


.. function:: relevance(validation_error)
    :noindex:

    A key function that sorts errors based on heuristic relevance.

    If you want to sort a bunch of errors entirely, you can use
    this function to do so. Using this function as a key to e.g.
    `sorted` or `max` will cause more relevant errors to be
    considered greater than less relevant ones.

    Within the different validation keywords that can fail, this
    function considers :kw:`anyOf` and :kw:`oneOf` to be *weak*
    validation errors, and will sort them lower than other errors at the
    same level in the instance.

    If you want to change the set of weak [or strong] validation
    keywords you can create a custom version of this function with
    `by_relevance` and provide a different set of each.

.. doctest::

    >>> schema = {
    ...     "properties": {
    ...         "name": {"type": "string"},
    ...         "phones": {
    ...             "properties": {
    ...                 "home": {"type": "string"}
    ...             },
    ...         },
    ...     },
    ... }
    >>> instance = {"name": 123, "phones": {"home": [123]}}
    >>> errors = Draft202012Validator(schema).iter_errors(instance)
    >>> [
    ...     e.path[-1]
    ...     for e in sorted(errors, key=exceptions.relevance)
    ... ]
    ['home', 'name']


.. autofunction:: by_relevance
    :noindex:
