# `AshGettext.ErrorTranslation`
[🔗](https://github.com/Undeadlol1/ash_gettext/blob/v0.1.0/lib/ash_gettext/error_translation.ex#L1)

Turn an Ash error's message into the reader's language.

Ash errors are Splode structs carrying a `:message` and a bag of `:vars`, and
every transport renders that same struct — JSON:API puts it in `detail`,
GraphQL in the error message, gRPC in the status. Translating the struct once
therefore covers every transport at once, including ones not written yet.

The `:message` *is* the msgid. A message the catalog covers is replaced; one it
does not is left exactly as it was, so adopting this can only ever add
translations, never mangle an existing message.

Ash's own errors with no message (a missing required value, a failed policy)
get the written sentence from `AshGettext.AshMessages`, translated, and come
back as an `AshGettext.AshMessages.Translated` that keeps the original.

Pure by construction: backend, text domain and locale are all arguments, so a
test is one assertion over one struct — no action run, no database, no actor.

`AshGettext.ErrorTranslation.ErrorHandler` calls this each time a create,
update or destroy action fails on a resource that uses `AshGettext.Resource`.
You can also call it yourself on any error you already hold.

# `option`

```elixir
@type option() ::
  {:backend, module()} | {:text_domain, String.t()} | {:locale, String.t()}
```

# `translate`

```elixir
@spec translate(term(), [option()]) :: term()
```

Translate `error`'s message, leaving anything untranslatable untouched.

Handles a bare error struct, a list of them, and a class error whose nested
`:errors` hold the real messages. An error with no message that
`AshGettext.AshMessages` lists gets its sentence; anything else without a
binary `:message` comes back as it was. Missing options raise `KeyError`.

    AshGettext.ErrorTranslation.translate(error,
      backend: MyApp.Gettext,
      text_domain: "ash",
      locale: "ru"
    )

## Options

  * `:backend` — required; the Gettext backend to look the msgid up in.
  * `:text_domain` — required; the gettext text domain to look it up under.
  * `:locale` — required; the locale to render in.

---

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