Jido.Error (Jido v2.3.0)

Copy Markdown View Source

Unified error handling for the Jido ecosystem using Splode.

Error Types

Six consolidated error types cover all failure scenarios:

ErrorUse Case
ValidationErrorInvalid inputs, actions, sensors, configs
ExecutionErrorRuntime failures during execution or planning
RoutingErrorSignal routing and dispatch failures
TimeoutErrorOperation timeouts
CompensationErrorSaga compensation failures
InternalErrorUnexpected system failures

Usage

# Validation failures (with optional kind)
Jido.Error.validation_error("Invalid email", kind: :input, field: :email)
Jido.Error.validation_error("Unknown action", kind: :action, action: MyAction)

# Execution failures (with optional phase)
Jido.Error.execution_error("Action failed", phase: :run)
Jido.Error.execution_error("Planning failed", phase: :planning)

# Routing/dispatch failures
Jido.Error.routing_error("No handler", target: "user.created")

# Timeouts
Jido.Error.timeout_error("Timed out", timeout: 5000)

# Internal errors
Jido.Error.internal_error("Unexpected failure")

Splode Error Classes

Errors are classified for aggregation (in order of precedence):

  • :invalid - Validation failures
  • :execution - Runtime failures
  • :routing - Routing/dispatch failures
  • :timeout - Timeouts
  • :internal - Unexpected failures

Summary

Functions

Creates a compensation error.

Creates an execution error.

Extracts the message string from a nested error structure.

Formats a NimbleOptions configuration error.

Formats a NimbleOptions validation error for parameters.

Creates an internal error.

Returns whether an error is safe to retry by default.

Creates a routing error.

Creates a timeout error.

Converts an error into a stable, public map.

Traverses errors, calling fun for each leaf error, and returns a nested map of results grouped by each error's path.

Raises an error if the result is an error, otherwise returns the result

Creates a validation error.

Types

class()

@type class() :: %{
  :__struct__ => class_module(),
  :__exception__ => true,
  :errors => [t()],
  :class => error_class(),
  :bread_crumbs => [String.t()],
  :vars => Keyword.t(),
  :stacktrace => Splode.Stacktrace.t() | nil,
  :context => map(),
  optional(atom()) => any()
}

class_module()

@type class_module() ::
  Jido.Error.Internal
  | Jido.Error.Timeout
  | Jido.Error.Routing
  | Jido.Error.Execution
  | Jido.Error.Invalid
  | Splode.Error.Unknown

error_class()

@type error_class() ::
  :internal | :timeout | :routing | :execution | :invalid | :unknown

t()

@type t() :: %{
  :__struct__ => module(),
  :__exception__ => true,
  :class => error_class(),
  :bread_crumbs => [String.t()],
  :vars => Keyword.t(),
  :stacktrace => Splode.Stacktrace.t() | nil,
  :context => map(),
  optional(atom()) => any()
}

Functions

compensation_error(message, opts \\ [])

@spec compensation_error(String.t(), keyword() | map()) ::
  Jido.Error.CompensationError.t()

Creates a compensation error.

Options

  • :original_error - The error that triggered compensation
  • :compensated - Whether compensation succeeded (default: false)
  • :result - Result from successful compensation
  • :details - Additional context map

execution_error(message, opts \\ [])

@spec execution_error(String.t(), keyword() | map()) :: Jido.Error.ExecutionError.t()

Creates an execution error.

Options

  • :phase - Where failure occurred: :execution, :planning
  • :details - Additional context map
  • Any other keys are merged into details

extract_message(error)

@spec extract_message(any()) :: String.t()

Extracts the message string from a nested error structure.

format_nimble_config_error(error, module_type, module)

@spec format_nimble_config_error(any(), String.t(), module()) :: String.t()

Formats a NimbleOptions configuration error.

format_nimble_validation_error(error, module_type, module)

@spec format_nimble_validation_error(any(), String.t(), module()) :: String.t()

Formats a NimbleOptions validation error for parameters.

internal_error(message, opts \\ [])

@spec internal_error(String.t(), keyword() | map()) :: Jido.Error.InternalError.t()

Creates an internal error.

Options

  • :details - Additional context map

retryable?(error)

@spec retryable?(term()) :: boolean()

Returns whether an error is safe to retry by default.

Explicit :retry, :retryable, and :retryable? boolean hints in structured details override the default classification.

routing_error(message, opts \\ [])

@spec routing_error(String.t(), keyword() | map()) :: Jido.Error.RoutingError.t()

Creates a routing error.

Options

  • :target - The intended routing target
  • :details - Additional context map

splode_error?(arg1, splode)

timeout_error(message, opts \\ [])

@spec timeout_error(String.t(), keyword() | map()) :: Jido.Error.TimeoutError.t()

Creates a timeout error.

Options

  • :timeout - The timeout value in milliseconds
  • :details - Additional context map

to_map(error)

@spec to_map(any()) :: map()

Converts an error into a stable, public map.

The returned map is suitable for transport and reporting boundaries. It includes bounded, sanitized details and never includes stacktraces by default.

traverse_errors(error_or_errors, fun)

Traverses errors, calling fun for each leaf error, and returns a nested map of results grouped by each error's path.

See Splode.traverse_errors/2 for full documentation.

Example

iex> Elixir.Jido.Error.traverse_errors(error, fn error ->
...>   Exception.message(error)
...> end)
%{name: ["name is required"]}

unwrap!(result, opts \\ nil)

Raises an error if the result is an error, otherwise returns the result

Alternatively, you can use the defsplode macro, which does this automatically.

Options

  • :error_opts - Options to pass to to_error/2 when converting the returned error
  • :unknown_error_opts - Options to pass to the unknown error if the function returns only :error. not necessary if your function always returns {:error, error}.

Examples

def function(arg) do

case do_something(arg) do
  :success -> :ok
  {:success, result} -> {:ok, result}
  {:error, error} -> {:error, error}
end

end

def function!(arg) do

YourErrors.unwrap!(function(arg))

end

validation_error(message, opts \\ [])

@spec validation_error(String.t(), keyword() | map()) ::
  Jido.Error.ValidationError.t()

Creates a validation error.

Options

  • :kind - Category: :input, :action, :sensor, :config
  • :subject - The invalid value
  • :field - Alias for :subject (for input validation)
  • :action - Alias for :subject with kind: :action
  • :sensor - Alias for :subject with kind: :sensor
  • :details - Additional context map

Examples

validation_error("Invalid email", field: :email)
validation_error("Unknown action", kind: :action, subject: MyAction)