# `ExternalService.ServiceNotStarted`
[🔗](https://github.com/jvoegele/external_service/blob/main/lib/external_service/errors.ex#L118)

Raised or returned when a call is made to a service that has not been started
with `ExternalService.start/2`.

This is an [Errata](https://hexdocs.pm/errata) infrastructure error. The same
value is returned in an `{:error, error}` tuple by `ExternalService.call/3` and
raised by `ExternalService.call!/3`. Its `:context` contains the `:service`
(the fuse name) that was not started.

Unlike the other errors, this one indicates a programming/configuration mistake
rather than a transient infrastructure failure, so its `http_status/1` is 500
and it is not retryable. Retrying cannot help: nothing changes until the
service is started.

# `t`

```elixir
@type t() :: Errata.infrastructure_error()
```

# `code`

```elixir
@spec code(Errata.error()) :: String.t() | nil
```

Returns the stable external code for this error, or `nil` if it has none.

No code is set for this error type. Set one with the `:code` option, or
override this function to derive a code from the error's `:reason` or
`:context`. See also `Errata.code/1`.

# `display_message`

```elixir
@spec display_message(Errata.error()) :: String.t() | nil
```

Returns the user-facing _display message_ for this error (the `:message` field by default).

This is distinct from `Exception.message/1`, which also includes the error's `:reason` and is
aimed at developers. Override this function to compute a message from the error's `:reason` or
`:context`:

    def display_message(%{context: %{order_id: id}}), do: "order #{id} does not exist"
    def display_message(error), do: error.message

`Errata.display_message/1` and `Errata.to_map/1` both dispatch through this function, so an
override applies to the JSON encoding and to anything rendering the error for a user. See also
`Errata.display_message/1`.

# `http_status`

```elixir
@spec http_status(Errata.error()) :: non_neg_integer()
```

Returns the HTTP status code associated with this error (`503` by default).

The default is derived from the error's kind, or set via the `:http_status`
option. Override this function to compute a status from the error's `:reason`
or `:context`. See also `Errata.http_status/1`.

# `redact_context`

```elixir
@spec redact_context(Errata.error()) :: map()
```

Returns this error's `:context` with sensitive values redacted (no keys declared).

Called wherever Errata serializes the context — `to_map/1` and the JSON
encoding, `Errata.log/2` metadata, and `Errata.report/2` telemetry metadata.
The error struct itself is left alone, so the real values remain available
locally for debugging.

Declared keys are redacted recursively and match whether written as atoms or
binaries. Set them with the `:redact` option, add a global floor with
`config :errata, redact: [...]`, or override this function for full control.
See `Errata.Redaction`.

# `retryable?`

```elixir
@spec retryable?(Errata.error()) :: boolean()
```

Returns whether this error is considered retryable (`false` by default).

The default is derived from the error's kind — `:infrastructure` errors are
retryable, `:domain` and `:general` errors are not — or set via the
`:retryable` option. Override this function to decide from the error's
`:reason` or `:context`. See also `Errata.retryable?/1`.

# `severity`

```elixir
@spec severity(Errata.error()) :: Logger.level()
```

Returns the severity of this error (`:error` by default).

The severity is a `t:Logger.level/0` and is the level at which `Errata.log/2`
logs the error when no level is given explicitly. Set it with the `:severity`
option, or override this function to compute a severity from the error's
`:reason` or `:context`. See also `Errata.severity/1`.

---

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