The error every Ramal function returns as {:error, %Ramal.Error{}}.
When a Ramal error is raised inside an Ash action (for example a bulk action inside a branch), Ash returns it in
the errors of an Ash.Error.Invalid; find/2 pulls it out.
reason is an atom from the closed list below, so a host can match on it. message says what happened in words
a developer can act on. details carries the data behind the message, for example the stale rows.
| reason | meaning |
|---|---|
:not_found | no branch with that id, in memory or in storage |
:not_open | the branch is not in the status the call needs: open for run/2, fork/2, merge/2 and propose/2, proposed for approve/2 and reject/2 |
:stale | the base moved under rows the branch read (details.rows) |
:merge_failed | a replayed action failed; details has index, type, resource, action and the Ash error |
:database_generated_key | a branch cannot create a row whose primary key the database generates |
:bulk_unsupported | a bulk create, update or destroy inside a branch |
:upsert_unsupported | an upsert inside a branch |
:multitenancy_unsupported | a multitenant resource used with a tenant inside a branch |
:branch_too_large | the branch process exceeded max_heap_size and was stopped |
:no_branchable_resources | the domain has no resource that opted in with Ramal.Resource |
:nested_branch | Ramal.run/2 was called inside another Ramal.run/2, or Ramal.merge/2 inside one |
:missing_snapshot | an overlay entry that needs the base row as first seen has none recorded |
:limit_reached | Ramal.branch/2 or Ramal.fork/2 was refused by :max_active_branches or :branch_rate of Ramal.Supervisor (details.limit, max, and active or window) |
:storage | the storage backend failed |
Example
iex> error = Ramal.Error.new(:not_open, "branch b1 is already merged", %{status: :merged})
iex> {error.reason, error.message, error.details}
{:not_open, "branch b1 is already merged", %{status: :merged}}
iex> Exception.message(error)
"branch b1 is already merged"
Summary
Functions
Create an Elixir.Ramal.Error without raising it.
The first Ramal.Error in an error Ash returned, or nil.
Builds an error.
Types
@type reason() ::
:not_found
| :not_open
| :stale
| :merge_failed
| :database_generated_key
| :bulk_unsupported
| :upsert_unsupported
| :multitenancy_unsupported
| :branch_too_large
| :no_branchable_resources
| :nested_branch
| :missing_snapshot
| :limit_reached
| :storage
Functions
@spec exception(opts :: Keyword.t()) :: %Ramal.Error{ __exception__: true, bread_crumbs: term(), class: term(), details: term(), message: term(), path: term(), reason: term(), splode: term(), stacktrace: term(), vars: term() }
Create an Elixir.Ramal.Error without raising it.
Keys
- :reason
- :message
- :details
The first Ramal.Error in an error Ash returned, or nil.
Ash wraps the errors of an action in an error class (Ash.Error.Invalid and friends) whose errors list holds
them. This looks through that list, so a host can match on the reason without knowing how Ash nested it.
Example
iex> error = Ramal.Error.new(:bulk_unsupported, "no bulk inside a branch")
iex> Ramal.Error.find(Ash.Error.to_error_class(error)).reason
:bulk_unsupported
iex> Ramal.Error.find(Ash.Error.to_error_class("something else"))
nil
Builds an error.
Example
iex> Ramal.Error.new(:not_found, "no branch with id \"b1\"").reason
:not_found