# `ExResilience.Chaos`
[🔗](https://github.com/joshrotenberg/ex_resilience/blob/v0.4.0/lib/ex_resilience/chaos.ex#L1)

Stateless fault injection for testing resilience pipelines.

Injects errors and/or latency into function calls based on configurable
probabilities. Useful for verifying that upstream resilience layers
(retry, circuit breaker, etc.) handle failures correctly.

## Options

  * `:name` -- optional atom for telemetry metadata. Default `:chaos`.
  * `:error_rate` -- probability of injecting an error (0.0 to 1.0). Default `0.0`.
  * `:error_fn` -- 0-arity function returning the error value.
    Default: `ExResilience.Chaos.default_error/0`.
  * `:latency_rate` -- probability of injecting latency (0.0 to 1.0). Default `0.0`.
  * `:latency_min` -- minimum injected latency in milliseconds. Default `0`.
  * `:latency_max` -- maximum injected latency in milliseconds. Default `100`.
  * `:seed` -- optional integer RNG seed for deterministic behavior.

## Execution Order

1. If `:seed` is provided, seed the process RNG.
2. Roll for latency injection. If triggered, sleep for a random duration
   in `[latency_min, latency_max]`.
3. Roll for error injection. If triggered, return `error_fn.()` without
   calling the wrapped function.
4. Otherwise, call the wrapped function and return its result.

## Examples

    iex> ExResilience.Chaos.call(fn -> {:ok, 1} end, error_rate: 0.0, latency_rate: 0.0)
    {:ok, 1}

    iex> ExResilience.Chaos.call(fn -> {:ok, 1} end, error_rate: 1.0)
    {:error, :chaos_fault}

# `option`

```elixir
@type option() ::
  {:name, atom()}
  | {:error_rate, float()}
  | {:error_fn, (-&gt; term())}
  | {:latency_rate, float()}
  | {:latency_min, non_neg_integer()}
  | {:latency_max, non_neg_integer()}
  | {:seed, integer()}
```

# `call`

```elixir
@spec call((-&gt; term()), [option()]) :: term()
```

Executes `fun` with optional fault injection.

See module documentation for available options and execution order.

## Examples

    iex> ExResilience.Chaos.call(fn -> :ok end, error_rate: 0.0)
    :ok

    iex> ExResilience.Chaos.call(fn -> :ok end, error_rate: 1.0, error_fn: fn -> {:error, :boom} end)
    {:error, :boom}

# `default_error`

```elixir
@spec default_error() :: {:error, :chaos_fault}
```

Returns the default error value used when no `:error_fn` is provided.

---

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