BB.Error (bb v0.15.0)

View Source

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

Summary

Types

t()

An error struct that implements BB.Error.Severity

Functions

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

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

Returns the severity of an error.

Types

t()

@type t() :: struct()

An error struct that implements BB.Error.Severity

Functions

__using__(opts)

(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?(error)

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

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

severity(error)

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

Returns the severity of an error.

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