# `Codex.Error`
[🔗](https://github.com/nshkrdotcom/codex_sdk/blob/v0.18.1/lib/codex/error.ex#L1)

Base error struct for Codex failures.

## Error Kinds

  * `:rate_limit` - API rate limit exceeded
  * `:sandbox_assessment_failed` - Sandbox assessment failed
  * `:unknown` - Unclassified error

## Rate Limit Handling

Rate limit errors may include a `retry_after_ms` hint extracted from
the API response. Use `retry_after_ms/1` to access this value.

# `kind`

```elixir
@type kind() ::
  :rate_limit
  | :sandbox_assessment_failed
  | :unknown
  | :realtime_connection_failed
  | :realtime_connection_closed
  | :realtime_session_error
  | :realtime_audio_error
  | :realtime_tool_error
  | :realtime_handoff_error
  | :realtime_guardrail_tripped
  | :voice_stt_error
  | :voice_stt_connection_error
  | :voice_tts_error
  | :voice_workflow_error
  | :voice_pipeline_error
  | :unsupported_feature
```

# `t`

```elixir
@type t() :: %Codex.Error{
  __exception__: true,
  details: map(),
  kind: kind(),
  message: String.t(),
  retry_after_ms: non_neg_integer() | nil
}
```

# `new`

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

# `normalize`

```elixir
@spec normalize(term()) :: t()
```

Normalizes raw error payloads into `%Codex.Error{}` structs.

Accepts maps emitted by codex-rs (`turn.failed`), basic strings, or already
constructed `%Codex.Error{}` structs. Known codes and types are classified
into stable `:kind` atoms so callers can branch on error domains (e.g.,
rate limits, sandbox assessment failures).

# `rate_limit`

```elixir
@spec rate_limit(
  String.t(),
  keyword()
) :: t()
```

Creates a rate limit error with optional retry-after hint.

## Options

  * `:retry_after_ms` - Suggested delay before retry in milliseconds
  * `:details` - Additional error details map

## Examples

    iex> error = Codex.Error.rate_limit("Rate limit exceeded", retry_after_ms: 30_000)
    iex> error.kind
    :rate_limit
    iex> error.retry_after_ms
    30_000

# `rate_limit?`

```elixir
@spec rate_limit?(t() | term()) :: boolean()
```

Checks if error is a rate limit error.

## Examples

    iex> error = Codex.Error.rate_limit("Rate limited")
    iex> Codex.Error.rate_limit?(error)
    true
    iex> Codex.Error.rate_limit?(%Codex.Error{kind: :unknown, message: "Other"})
    false

# `realtime_audio_error`

```elixir
@spec realtime_audio_error(keyword()) :: t()
```

Creates a realtime audio error.

# `realtime_connection_closed`

```elixir
@spec realtime_connection_closed(keyword()) :: t()
```

Creates a realtime connection closed error.

# `realtime_connection_failed`

```elixir
@spec realtime_connection_failed(keyword()) :: t()
```

Creates a realtime connection failed error.

# `realtime_guardrail_tripped`

```elixir
@spec realtime_guardrail_tripped(keyword()) :: t()
```

Creates a realtime guardrail tripped error.

# `realtime_handoff_error`

```elixir
@spec realtime_handoff_error(keyword()) :: t()
```

Creates a realtime handoff error.

# `realtime_session_error`

```elixir
@spec realtime_session_error(keyword()) :: t()
```

Creates a realtime session error.

# `realtime_tool_error`

```elixir
@spec realtime_tool_error(keyword()) :: t()
```

Creates a realtime tool error.

# `retry_after_ms`

```elixir
@spec retry_after_ms(t()) :: non_neg_integer() | nil
```

Extracts retry-after hint from error if present.

Returns the delay in milliseconds, or `nil` if not available.

## Examples

    iex> error = Codex.Error.rate_limit("Rate limited", retry_after_ms: 60_000)
    iex> Codex.Error.retry_after_ms(error)
    60_000
    iex> Codex.Error.retry_after_ms(%Codex.Error{kind: :unknown, message: "Other"})
    nil

# `voice_pipeline_error`

```elixir
@spec voice_pipeline_error(keyword()) :: t()
```

Creates a voice pipeline error.

# `voice_stt_connection_error`

```elixir
@spec voice_stt_connection_error(keyword()) :: t()
```

Creates a voice STT connection error.

# `voice_stt_error`

```elixir
@spec voice_stt_error(keyword()) :: t()
```

Creates a voice STT (speech-to-text) error.

# `voice_tts_error`

```elixir
@spec voice_tts_error(keyword()) :: t()
```

Creates a voice TTS (text-to-speech) error.

# `voice_workflow_error`

```elixir
@spec voice_workflow_error(keyword()) :: t()
```

Creates a voice workflow error.

---

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