# `SfVoiceMedia.Error`
[🔗](https://github.com/sf-voice/sf-voice-core/blob/main/lib/sf_voice_media/error.ex#L1)

structured error returned by every SDK function on failure.

raised as an exception by `SfVoiceMedia.poll_task/3` on timeout or task failure;
returned inside `{:error, %SfVoiceMedia.Error{}}` tuples by all other functions.

fields:
- `code`    — machine-readable error code string from the API (e.g. `"not_found"`)
- `message` — human-readable description
- `status`  — http status code, or `nil` when the error is client-side (e.g. poll timeout)

# `t`

```elixir
@type t() :: %SfVoiceMedia.Error{
  __exception__: true,
  code: String.t(),
  message: String.t(),
  status: non_neg_integer() | nil
}
```

# `from_response`

```elixir
@spec from_response(non_neg_integer(), map() | nil) :: t()
```

Builds an SfVoiceMedia.Error from the API error envelope.

Parses a response body with the shape `%{"error" => %{"code" => code, "message" => message}}`
and returns an `%SfVoiceMedia.Error{}` populated with `code`, `message`, and the given HTTP `status`.
If the body does not match that shape, the function falls back to a generic HTTP error.
`message: "request failed with status <status>"`, and `status` set to the given status.

## Parameters

  - status: HTTP status code returned by the request.
  - body: Parsed response body (map) or `nil`.

# `message`

```elixir
@spec message(t()) :: String.t()
```

Format the exception into a human-readable string.

Formats an `%SfVoiceMedia.Error{}` as `"[<code>] <message> (HTTP <status>)"`.

# `poll_timeout`

```elixir
@spec poll_timeout(String.t(), non_neg_integer()) :: t()
```

Create a client-side timeout error for a polling task.

The returned `%SfVoiceMedia.Error{}` has `code: "poll_timeout"`, a `message` that includes the `task_id` and `timeout_ms`, and `status: nil`.

---

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