# `BB.Error`
[🔗](https://github.com/beam-bots/bb/blob/main/lib/bb/error.ex#L5)

Structured error handling for the Beam Bots ecosystem.

This module wraps `Splode.Error` with compile-time enforcement of the
`BB.Error.Severity` protocol. All error types in BB must implement this
protocol to ensure consistent severity classification.

## Usage

Define error types using `use BB.Error`:

    defmodule BB.Error.Hardware.Timeout do
      use BB.Error, class: :hardware, fields: [:device, :timeout_ms]

      defimpl BB.Error.Severity do
        def severity(_), do: :error
      end

      def message(%{device: device, timeout_ms: timeout_ms}) do
        "Hardware timeout on #{inspect(device)} after #{timeout_ms}ms"
      end
    end

## Error Classes

The following error classes are defined:

- `:hardware` - Communication failures with physical devices
- `:safety` - Safety system violations (always `:critical` severity)
- `:kinematics` - Motion planning failures
- `:invalid` - Configuration and validation errors
- `:state` - State machine violations
- `:protocol` - Low-level protocol failures (Robotis, I2C, etc.)

## Severity Protocol

Each error must implement `BB.Error.Severity`, which returns one of:

- `:critical` - Immediate safety response required
- `:error` - Operation failed, may retry or degrade
- `:warning` - Unusual condition, operation continues

# `t`

```elixir
@type t() :: struct()
```

An error struct that implements `BB.Error.Severity`

# `__using__`
*macro* 

Use this macro to define error types. Wraps `Splode.Error` and enforces
`BB.Error.Severity` protocol implementation at compile time.

## Options

- `:class` - Required. The error class (`:hardware`, `:safety`, etc.)
- `:fields` - Optional. List of fields for this error type.

## Example

    defmodule BB.Error.Safety.LimitExceeded do
      use BB.Error,
        class: :safety,
        fields: [:joint, :limit_type, :measured, :limit]

      defimpl BB.Error.Severity do
        def severity(_), do: :critical
      end

      def message(%{joint: joint, limit_type: type, measured: measured, limit: limit}) do
        "Joint #{inspect(joint)} #{type} limit exceeded: #{measured} vs limit #{limit}"
      end
    end

# `critical?`

```elixir
@spec critical?(t()) :: boolean()
```

Returns `true` if the error is critical (severity = `:critical`).

# `severity`

```elixir
@spec severity(t()) :: :critical | :error | :warning
```

Returns the severity of an error.

Delegates to `BB.Error.Severity.severity/1`.

---

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