Defines an application Error with validated kinds, public payloads, and exception text.
Use the guides for design, application usage, Ecto, custom sources, and output and logging.
Catalog
defmodule MyApp.Error do
use RintoError
catalog do
entry :local
entry :missing, http_status: 404
entry :broken, as: :unavailable, http_status: 503
end
endentry declares a constructable internal kind. entry_for Source, :kind
also registers an exact struct type; its module must be available at compile
time. Both accept these optional literal values:
as:— public name, defaulting to the internal kind. Mapping happens once; output-only names are not constructable unless separately declared.http_status:— integer from100to599, looked up by internal kind. Missing statuses raiseArgumentErroronly whenhttp_status/1is called.doc:— string included in catalog details, without affecting error behavior.
Kinds and output names must be atom literals other than nil, true, and
false. Variables, module attributes, and computed expressions are rejected,
as are duplicate kinds, source registrations, options, and unknown options.
A module may have one catalog; an empty or omitted catalog accepts no inputs.
kinds() lists declared kinds; kinds(:full) includes names, statuses, and
docs; kinds(:public) groups those details by output name. All preserve declaration
order. source_kinds(), payload_kinds(), and statuses() expose source
registrations, changed output names, and explicitly configured statuses.
Construction
require MyApp.Error, as: Error
Error.new(:missing)
Error.new(kind: :broken, raw: :db_down, data: %{attempt: 2})new/2 constructs an Error and records the call site in metadata.origin.
It evaluates input and message once; a non-nil message, including "", replaces
the existing message. exception/1 and raise Error, opts do not record origin.
Atom input sets both kind and raw. Map/keyword input defaults raw to nil
and requires kind unless a registered __source__ supplies it. Unknown fields
raise KeyError; missing required fields raise ArgumentError. Registered
structs use RintoError.Source; unregistered structs raise ArgumentError.
Undeclared literal kinds passed directly to new fail compilation. Dynamic
inputs and builder results are validated at construction, raising ArgumentError
for undeclared kinds. Direct struct construction requires kind and raw but,
like direct map updates, bypasses catalog validation.
Output
to_payload/1 returns %{kind: atom(), data: map(), errors: [term()]} with the
mapped kind, excluding raw, message, metadata, and the source selector.
Without a source, data and details are emitted as stored. Source conversion
uses RintoError.Source.to_payload/2; details are never recursively converted or mapped.
If JSON.Encoder or Jason.Encoder is loaded when the Error module compiles,
the corresponding implementation is generated and encodes through to_payload/1.
The library does not send responses or emit logs.
Options
inspect_opts:— options for field values in exception text. They merge overconfig :rinto_error, inspect_opts: [...], which merges over defaults[pretty: true, width: 80, limit: :infinity, printable_limit: :infinity]. Application configuration is read per call; module options are captured at compile time. Empty lists inherit prior options. This does not affectinspect(error)or payloads.
Override message/1 in the Error module to customize exception/log text;
super(error) reuses the default formatter. Default text contains kind, message,
data, errors, and metadata, excluding raw and the source selector.
Ecto registration is always explicit. Its standard RintoError.Source
implementation follows the same protocol contract as custom sources.
See RintoError.Source for implementation and build validation details.
Generated types
Reference types on your application module, such as MyApp.Error.t():
t()/t(raw_type)— Error with arbitrary / specified raw data. The parameter constrains raw, not kind; the kind field remainsatom().known_kind()— union of declared internal kinds;none()for an empty catalog.payload()— public output;kind_detail()— one catalog declaration.origin()/metadata()— construction location / diagnostic context.
Typespecs do not add runtime checks; construction enforces catalog membership.
Migrating earlier APIs
Replace positional declarations and public:, expose_as:, construct:, or
status: with entry :kind, as: :name, http_status: 422. Replace changeset: /
changeset_kind: with entry_for Ecto.Changeset, :kind.
The use RintoError options exclude_default_sources and override_sources
are no longer supported.
To replace the supplied Changeset implementation, configure
config :rinto_error, exclude_default_sources: [Ecto.Changeset] before compiling
the dependency, then define your own defimpl. Protocol implementations apply
globally per source type; use a wrapper struct for coexisting behaviors.
Replace expand/2 or two-argument builders with build/1 returning attributes.
Replace @behaviour RintoError.Payload and to_payload(error) with the protocol
function to_payload(_source, error) in the same defimpl. Both protocol
functions are required; the first output argument only selects the source type.
Manual attributes must set __source__ explicitly
instead of relying on raw's type. Ecto type descriptions now use t objects
instead of scalar names or composite name keys; see RintoError.Changeset.
Summary
Functions
Declares this module's error table. A module may have only one catalog.
The block may contain only entry and entry_for calls.