# `Dsxir.Errors`

Splode aggregator for dsxir-originated errors.

Six classes, ordered by precedence (first non-empty class wins on aggregation):

  * `:halted` - explicit policy halts (e.g. `call_plugs` returning `{:halt, _}`).
  * `:invalid` - configuration / input / signature shape problems.
  * `:adapter` - parse, validation, and fallback exhaustion errors.
  * `:lm` - upstream LM transport / quota / context-window errors.
  * `:framework` - dsxir internal bugs surfaced as typed errors.
  * `:unknown` - Splode fallback when an error cannot be classified.

Every dsxir-originated error carries a `path` field populated as the call
descends nested predictors — e.g. `[:extract_actions, :action_items]`.

# `class`

```elixir
@type class() :: %{
  :__struct__ =&gt; class_module(),
  :__exception__ =&gt; true,
  :errors =&gt; [t()],
  :class =&gt; error_class(),
  :bread_crumbs =&gt; [String.t()],
  :vars =&gt; Keyword.t(),
  :stacktrace =&gt; Splode.Stacktrace.t() | nil,
  :context =&gt; map(),
  optional(atom()) =&gt; any()
}
```

# `class_module`

```elixir
@type class_module() ::
  Dsxir.Errors.Unknown
  | Dsxir.Errors.Framework
  | Dsxir.Errors.LM
  | Dsxir.Errors.Adapter
  | Dsxir.Errors.Invalid
  | Dsxir.Errors.Halted
```

# `error_class`

```elixir
@type error_class() :: :unknown | :framework | :lm | :adapter | :invalid | :halted
```

# `t`

```elixir
@type t() :: %{
  :__struct__ =&gt; module(),
  :__exception__ =&gt; true,
  :class =&gt; error_class(),
  :bread_crumbs =&gt; [String.t()],
  :vars =&gt; Keyword.t(),
  :stacktrace =&gt; Splode.Stacktrace.t() | nil,
  :context =&gt; map(),
  optional(atom()) =&gt; any()
}
```

# `class_of`

```elixir
@spec class_of(any()) :: atom()
```

Return the splode class of `error` (one of `:halted`, `:invalid`, `:adapter`,
`:lm`, `:framework`, `:unknown`). Falls back to `:unknown` when the value is
not a classified dsxir error.

# `splode_error?`

# `traverse_errors`

Traverses errors, calling `fun` for each leaf error, and returns a nested
map of results grouped by each error's `path`.

See `Splode.traverse_errors/2` for full documentation.

## Example

    iex> Elixir.Dsxir.Errors.traverse_errors(error, fn error ->
    ...>   Exception.message(error)
    ...> end)
    %{name: ["name is required"]}

# `unwrap!`

Raises an error if the result is an error, otherwise returns the result

Alternatively, you can use the `defsplode` macro, which does this automatically.

### Options

- `:error_opts` - Options to pass to `to_error/2` when converting the returned error
- `:unknown_error_opts` - Options to pass to the unknown error if the function returns only `:error`.
  not necessary if your function always returns `{:error, error}`.

### Examples

  def function(arg) do
    case do_something(arg) do
      :success -> :ok
      {:success, result} -> {:ok, result}
      {:error, error} -> {:error, error}
    end
  end

  def function!(arg) do
    YourErrors.unwrap!(function(arg))
  end

---

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