Module error

error
Stability: unstable — may still change; see below.

Standard error handling types and traits for Yo.

Stability

unstable — the Error trait, AnyError, Exception and the IoExn bundle are the core of every fallible API in std and their shapes are settled. The one thing that blocked freezing them was a COMPILER defect, not a design gap: source()'s Option(Dyn(SelfTrait)) result had lost the Error trait on an erased receiver, so a caller could follow one link and print it but could not store, re-erase, downcast or re-throw it — and ErrorChain/root_cause are exactly that store.

That defect is FIXED (2026-09-14, TraitT identity is the trait's id rather than its externally-attached name — issues/fixed/self-trait-in-a-return-type-loses-the-trait-on-an-erased-receiver.md, filed as #521). The walk type-checks and runs; it is gated by tests/error_source_chain.test.yo.

ErrorChain/root_cause were then held one more release by the usual two-release sequencing — std/ is compiled by the SEED during bootstrap, so std code performing the walk could not build until a seed carried the fix. v0.2.34 is that seed, and both landed: root_cause(err) for the innermost error and error_chain(err) for the whole walk as an Iterator. Nothing in this module is waiting on a compiler defect or a decision.

Types

AnyError type-alias
dyn(ToString + Error)

Type-erased dynamic error type. Wraps any type implementing Error.

Context struct
Context

An error that adds a message to the one underneath it — Rust's anyhow::Context / .context(...).

This is the type that makes Error.source worth having: nothing else in the tree overrides it, so before this every error chain was one link long. to_string renders the whole chain, innermost last:

e := Context.new(`while loading the config`, dyn(io_err));
println(e.to_string());   // while loading the config: no such file

Fields

NameTypeDescription
messageString

What was being attempted.

causedyn(ToString + Error)

The error that caused it.

Trait Implementations

impl(Context, ...)
new : (Context) fn(message : String, cause : dyn(ToString + Error)) -> Context

Wrap cause with message.

Parameters

NameTypeNotesDescription
messageString

What was being attempted.

causedyn(ToString + Error)

The error that caused it.

Returns: Context

impl(Context, ToString(...))
to_string : (Context) fn(inout(self) : Context) -> String

Render self as the text a USER should read — Rust's Display::fmt, not its Debug. Hand-written (or generated by derive(Error) from a per-variant format string) whenever the structural form would be wrong.

Parameters

NameTypeNotes
selfContext

Returns: String

impl(Context, Error(...))
source : (Context) fn(inout(self) : Context) -> Option(dyn(ToString + ))

The error that caused this one, or .None at the root of the chain.

Rust's Error::source. Defaulted to .None, so an error with nothing underneath it implements the trait by saying only what it is; a wrapper overrides it to hand back what it wrapped. Walking the chain to the root cause works as of 2026-09-14 — the returned Dyn used to lose the Error trait on an erased receiver, so a caller could print one link but not follow it (#521, issues/fixed/self-trait-in-a-return-type-loses-the-trait-on-an-erased-receiver.md).

Parameters

NameTypeNotes
selfContext

Returns: Option(dyn(ToString + ))

Exception struct
Exception

Non-resumable exception handling effect record. Use throw to raise an AnyError and abort the current computation. throw is ctl(...) — handler body may contain unwind, and the handler value is frame-bound (see plans/archive/EXPLICIT_EFFECTS.md §4).

Fields

NameTypeDescription
throwctl(generic(ResumeType) error : dyn(ToString + Error)) -> ResumeType
ResumableException type-function
fn(ResumeType : Type) -> Type

Creates a resumable exception effect record parameterized by the resume type. Unlike Exception, the handler can return a value to resume the computation. throw is still ctl(...) because the handler MAY choose to unwind; regular fn returns are also valid via subtyping fn <: ctl.

Type Parameters

NameTypeNotes
ResumeTypeTypecomptime
ErrorChain object
ErrorChain

An iterator over an error and everything underneath it — Rust's anyhow::Error::chain / std::error::Report's walk.

The first next() yields the error the chain was built from, then each source() in turn, ending when one reports .None. So a chain always has at least one link.

{ error_chain } :: import("std/error");

(e : AnyError) = dyn(Context.new(`while loading config`, io_err));
(n : usize) = usize(0);
it := error_chain(e);
(going : bool) = true;
while(runtime(going), {
  match(it.next(), .Some(link) => { n = (n + usize(1)); }, .None => { going = false; });
});

The cursor is spelled with match rather than Option's inherent methods throughout: Option(Dyn(Trait)) cannot take one — the specialization is called but never emitted, so the C fails to compile (issues/fixed/option-of-a-trait-object-never-emits-its-inherent-methods.md).

Fields

NameTypeDescription
_curOption(dyn(ToString + ))

Trait Implementations

impl(generic(I : Type), where(I <: Iterator), I : (Iterator))
into_iter : fn(self : I : (Iterator)) -> I

Parameters

NameTypeNotes
selfI : (Iterator)

Returns: I : (Iterator)

impl(generic(I : Type), where(I <: Iterator), I : (Iterator))
map : fn(generic(A, B, F) self : I : (Iterator), f : F : (Fn(A) -> B)) -> IterMap(I : (Iterator), B, F : (Fn(A) -> B))

Parameters

NameTypeNotes
selfI : (Iterator)
fF : (Fn(A) -> B)

Returns: IterMap(I : (Iterator), B, F : (Fn(A) -> B))

filter : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterFilter(I : (Iterator), F : (Fn(A) -> bool))

Parameters

NameTypeNotes
selfI : (Iterator)
fF : (Fn(A) -> bool)

Returns: IterFilter(I : (Iterator), F : (Fn(A) -> bool))

take : fn(generic(A) self : I : (Iterator), n : usize) -> IterTake(I : (Iterator))

Parameters

NameTypeNotes
selfI : (Iterator)
nusize

Returns: IterTake(I : (Iterator))

skip : fn(generic(A) self : I : (Iterator), n : usize) -> IterSkip(I : (Iterator))

Parameters

NameTypeNotes
selfI : (Iterator)
nusize

Returns: IterSkip(I : (Iterator))

enumerate : fn(generic(A) self : I : (Iterator)) -> IterEnumerate(I : (Iterator))

Parameters

NameTypeNotes
selfI : (Iterator)

Returns: IterEnumerate(I : (Iterator))

zip : fn(generic(A, J, B) self : I : (Iterator), other : J : (Iterator)) -> IterZip(I : (Iterator), J : (Iterator))

Parameters

NameTypeNotes
selfI : (Iterator)
otherJ : (Iterator)

Returns: IterZip(I : (Iterator), J : (Iterator))

fold : fn(generic(A, Acc, F) self : I : (Iterator), init : Acc, f : F : (Fn(Acc, A) -> Acc)) -> Acc

Parameters

NameTypeNotes
selfI : (Iterator)
initAcc
fF : (Fn(Acc, A) -> Acc)

Returns: Acc

for_each : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> unit)) -> unit

Parameters

NameTypeNotes
selfI : (Iterator)
fF : (Fn(A) -> unit)

Returns: unit

count : fn(generic(A) self : I : (Iterator)) -> usize

Parameters

NameTypeNotes
selfI : (Iterator)

Returns: usize

any : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> bool

Parameters

NameTypeNotes
selfI : (Iterator)
predF : (Fn(A) -> bool)

Returns: bool

all : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> bool

Parameters

NameTypeNotes
selfI : (Iterator)
predF : (Fn(A) -> bool)

Returns: bool

find : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> Option(A)

Parameters

NameTypeNotes
selfI : (Iterator)
predF : (Fn(A) -> bool)

Returns: Option(A)

position : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> Option(usize)

Parameters

NameTypeNotes
selfI : (Iterator)
predF : (Fn(A) -> bool)

Returns: Option(usize)

last : fn(generic(A) self : I : (Iterator)) -> Option(A)

Parameters

NameTypeNotes
selfI : (Iterator)

Returns: Option(A)

nth : fn(generic(A) self : I : (Iterator), n : usize) -> Option(A)

Parameters

NameTypeNotes
selfI : (Iterator)
nusize

Returns: Option(A)

sum : fn(generic(A) self : I : (Iterator)) -> A : ((Output : Type, + : fn(lhs : Self, rhs : A) -> Output) + Default)

Parameters

NameTypeNotes
selfI : (Iterator)

Returns: A : ((Output : Type, + : fn(lhs : Self, rhs : A) -> Output) + Default)

min : fn(generic(A) self : I : (Iterator)) -> Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))

Parameters

NameTypeNotes
selfI : (Iterator)

Returns: Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))

max : fn(generic(A) self : I : (Iterator)) -> Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))

Parameters

NameTypeNotes
selfI : (Iterator)

Returns: Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))

chain : fn(generic(A, J) self : I : (Iterator), other : J : (Iterator)) -> IterChain(I : (Iterator), J : (Iterator))

Parameters

NameTypeNotes
selfI : (Iterator)
otherJ : (Iterator)

Returns: IterChain(I : (Iterator), J : (Iterator))

take_while : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterTakeWhile(I : (Iterator), F : (Fn(A) -> bool))

Parameters

NameTypeNotes
selfI : (Iterator)
fF : (Fn(A) -> bool)

Returns: IterTakeWhile(I : (Iterator), F : (Fn(A) -> bool))

skip_while : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterSkipWhile(I : (Iterator), F : (Fn(A) -> bool))

Parameters

NameTypeNotes
selfI : (Iterator)
fF : (Fn(A) -> bool)

Returns: IterSkipWhile(I : (Iterator), F : (Fn(A) -> bool))

filter_map : fn(generic(A, B, F) self : I : (Iterator), f : F : (Fn(A) -> Option(B))) -> IterFilterMap(I : (Iterator), B, F : (Fn(A) -> Option(B)))

Parameters

NameTypeNotes
selfI : (Iterator)
fF : (Fn(A) -> Option(B))

Returns: IterFilterMap(I : (Iterator), B, F : (Fn(A) -> Option(B)))

peekable : fn(generic(A) self : I : (Iterator)) -> IterPeekable(I : (Iterator), A)

Parameters

NameTypeNotes
selfI : (Iterator)

Returns: IterPeekable(I : (Iterator), A)

collect : fn(self : I : (Iterator), C : Type) -> C : (FromIterator)

Parameters

NameTypeNotes
selfI : (Iterator)
CTypecomptime

Returns: C : (FromIterator)

impl(ErrorChain, Iterator(...))
Item : AnyError
next : (ErrorChain) fn(inout(self) : ErrorChain) -> Option(dyn(ToString + ))

Advance the iterator and return the next value, or None when exhausted.

Parameters

NameTypeNotes
selfErrorChain

Returns: Option(dyn(ToString + ))

IoExn struct
IoExn

Fields

NameTypeDescription
ioIo
exnException

Traits / Modules

Error trait
Error

Standard error trait for typed error propagation. All error types should implement this trait along with ToString.

Methods

source : fn(inout(self) : Self : (ToString)) -> Option(dyn(ToString + ))

The error that caused this one, or .None at the root of the chain.

Rust's Error::source. Defaulted to .None, so an error with nothing underneath it implements the trait by saying only what it is; a wrapper overrides it to hand back what it wrapped. Walking the chain to the root cause works as of 2026-09-14 — the returned Dyn used to lose the Error trait on an erased receiver, so a caller could print one link but not follow it (#521, issues/fixed/self-trait-in-a-return-type-loses-the-trait-on-an-erased-receiver.md).

Parameters

NameTypeNotes
selfSelf : (ToString)

Returns: Option(dyn(ToString + ))

Implementors

Functions

root_cause function
fn(err : AnyError) -> AnyError

Common effect bundle: Io + Exception. Used as the effect parameter for Futures that perform Io and may throw. Construct with { io, exn }; project with e.io or e.exn. The innermost error in a chain — Rust's anyhow::Error::root_cause.

Follows source() until an error reports none, and returns that one. An error with nothing underneath it is its own root cause, so this never returns .None and callers need no unwrapping.

{ root_cause } :: import("std/error");
e := dyn(Context.new(`while loading the config`, dyn(io_err)));
println(root_cause(e).to_string());   // the io error, not the context

Spelled with match rather than Option methods deliberately: the result of source() is an Option(Dyn(Error)), and an Option of a trait object cannot take an inherent Option method — the specialization is called but never emitted, so the C fails to compile (issues/fixed/option-of-a-trait-object-never-emits-its-inherent-methods.md). That is a separate open defect; this walk stays clear of it.

Parameters

NameTypeNotes
errAnyError

Returns: AnyError

error_chain function
fn(err : AnyError) -> ErrorChain

Start a chain at err. The first next() returns err itself.

Parameters

NameTypeNotes
errAnyError

Returns: ErrorChain