# `JSV.ErrorFormatter`
[🔗](https://github.com/lud/jsv/blob/v0.23.0/lib/jsv/error_formatter.ex#L1)

Error formatting helpers.

Errors are grouped by:

* Instance location: the bit of data that was invalidated
* Schema location: the part of the schema that invalidated it
* Evaluation path: the path followed from the root to this schema location

## Error levels

Each error carries a level, an integer describing how much information the
error message adds on its own. Consumers that only want actionable messages
can pass `:min_error_level` to `normalize_error/2` instead of blacklisting
keywords.

The levels used by the vocabularies shipped with this library are:

| Level | Meaning | Example |
| ----- | ------- | ------- |
| `5` | The message only points at a deeper error. | `property 'name' did not conform to the property schema` |
| `8` | The data is rejected by a rule that belongs to the parent, and the error on the parent reports it. | `value was rejected from boolean schema: false`, under a schema that already reported `additional properties are not allowed but found property 'extra'` |
| `10` | The error states why the data was rejected. | `value is not of type string` |

Errors are assigned `10` when `c:JSV.Vocabulary.format_error/3`
does not return a `:level` key. Custom vocabularies can return any integer,
including values between or below the ones listed above.

# `error_unit`

```elixir
@type error_unit() :: %{
  :valid =&gt; boolean(),
  :instanceLocation =&gt; binary(),
  :evaluationPath =&gt; binary(),
  :schemaLocation =&gt; binary(),
  optional(:errors) =&gt; [keyword_error()]
}
```

# `keyword_error`

```elixir
@type keyword_error() :: %{
  :kind =&gt; atom(),
  :message =&gt; String.t(),
  optional(:details) =&gt; [error_unit()]
}
```

# `level`

```elixir
@type level() :: integer()
```

# `normalize_opt`

```elixir
@type normalize_opt() ::
  {:sort, :asc | :desc}
  | {:keys, :atoms | :strings}
  | {:min_error_level, level()}
```

# `raw_path`

```elixir
@type raw_path() :: [raw_path()] | binary() | integer() | atom()
```

# `format_data_path`

```elixir
@spec format_data_path(raw_path()) :: String.t()
```

Formats a data path into a JSON pointer string prefixed with `#`.

The path is given in reverse order, as stored in errors and validation
contexts. For instance, a path pointing to the first element of a `"users"`
array is given as `[0, "users"]` and formatted as `"#/users/0"`.

# `level_default`

```elixir
@spec level_default() :: level()
```

Returns `10`, the level given to errors that do not define
their own level.

# `level_intermediary`

```elixir
@spec level_intermediary() :: level()
```

Returns `5`, the level given to errors whose message only
points at a deeper error.

# `level_parent_reported`

```elixir
@spec level_parent_reported() :: level()
```

Returns `8`, the level given to errors describing a
rejection that belongs to the parent data, and that an error on the parent
already reports.

# `normalize_error`

```elixir
@spec normalize_error(JSV.ValidationError.t(), keyword()) :: map()
```

Returns a JSON-able version of the errors contained in the ValidationError.

This is generatlly useful to generate HTTP API responses or message broker
responses.

### Options

* `:sort` (`:asc | :desc`) - Controls the sort direction. Errors are sorted by
  `instanceLocation`. The default value is `:desc`.

* `:keys` (`:atoms | :strings`) - Define the type of the keys in the
  normalized errors maps.

  While truly "normalized" JSON data should not have atom keys, this option
  defaults to :atoms for backward compatibility reasons.

* `:min_error_level` (integer) - Drops the errors whose level is below the
  given value, as well as the error units left without any error. See the
  "Error levels" section in `JSV.ErrorFormatter`. The default value is
  `0`, which keeps all errors defined by this library.

  Passing `8` drops the errors that only point at a
  deeper error, and `10` also drops the errors reported by an
  error on the parent data.

# `valid_annot`

```elixir
@spec valid_annot(JSV.Validator.validator(), JSV.Validator.context()) :: error_unit()
```

Returns an output unit with `valid: true` for the given
`JSV.Validator`. This can be substitued to an Error struct in the
nested details of an error. Mostly used to show multiple validated schemas
with `:oneOf`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
