# `DDD.Error`
[🔗](https://github.com/blackuprise/vicander/blob/v0.1.1/lib/ddd/model/error.ex#L1)

Structured error produced by the framework.

  * `:kind`       - `:business` (the domain said no; retrying gives the same answer) or
    `:infrastructure` (the system failed; retrying may succeed). Event handlers use it:
    a business error is a recorded rejection, an infrastructure error is retried.
  * `:entity`     - business entity (module) that produced the error
  * `:entity_id`  - the identity (`Entity.identity/1`) of the instance it happened to, or `nil`
    when there is none yet or it can't be told (a `new` call that is missing its identity)
  * `:operation`  - operation being run (`:new`, `:update`, `:validate` or a `defop` name)
  * `:code`       - machine-matchable code, e.g. `:validation_failed`
  * `:message`    - human-readable message
  * `:details`    - data produced by the rule that failed
  * `:violations` - list of `%{field, code, message, details}` when several rules failed
  * `:context`    - added by outer layers (running a command adds `:command`)

# `kind`

```elixir
@type kind() :: :business | :infrastructure
```

# `t`

```elixir
@type t() :: %DDD.Error{
  code: atom(),
  context: map(),
  details: map(),
  entity: module() | nil,
  entity_id: String.t() | nil,
  kind: kind(),
  message: String.t(),
  operation: atom() | nil,
  violations: [violation()]
}
```

# `violation`

```elixir
@type violation() :: %{
  field: atom(),
  code: atom(),
  message: String.t(),
  details: map()
}
```

# `business`

```elixir
@spec business(keyword() | map()) :: t()
```

Build a business error: the domain decided no. Never retried.

# `business?`

```elixir
@spec business?(t()) :: boolean()
```

True for business errors.

# `codes`

```elixir
@spec codes(t()) :: [atom()]
```

All violation codes of an error (or `[code]` when there are no violations).

# `has_code?`

```elixir
@spec has_code?(t(), atom()) :: boolean()
```

True when the error, or any of its violations, has the given code.

# `infrastructure`

```elixir
@spec infrastructure(keyword() | map()) :: t()
```

Build an infrastructure error: the system failed. Retried by event handlers.

# `infrastructure?`

```elixir
@spec infrastructure?(t()) :: boolean()
```

True for infrastructure errors.

# `new`

```elixir
@spec new(keyword() | map()) :: t()
```

Build an error from a keyword list or map.

# `put_context`

```elixir
@spec put_context(t(), map() | keyword()) :: t()
```

Merge extra context into the error.

# `to_map`

```elixir
@spec to_map(t()) :: %{required(atom()) =&gt; [String.t()]}
```

Per-field map of messages (form style): `%{field => [message]}`.
Errors without violations are reported under `:base`.

# `validation_failed`

```elixir
@spec validation_failed(module(), atom(), [violation()], String.t() | nil) :: t()
```

Build a `:validation_failed` error from a non-empty list of violations.

# `violation`

```elixir
@spec violation(atom(), atom(), String.t(), map()) :: violation()
```

Build a violation map (one failed rule).

# `wrap`

```elixir
@spec wrap(any(), map() | keyword()) :: t()
```

Convert any error reason into a `DDD.Error`, merging `context`.

Errors pass through. Atoms and `{code, message}` tuples are wrapped as `:business`
errors (a plain reason is the domain's answer). An exception becomes an `:infrastructure`
error with code `:exception`. Anything else becomes `:unknown` (business) with the
inspected reason in `details`.

---

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