Module error

error
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. What is missing is the part a real error story needs and this one does not have: **`ErrorChain` and `root_cause` cannot be written today**, and it is a compiler defect rather than a design gap (`issues/self-trait-in-a-return-type-loses-the-trait-on-an-erased-receiver.md`, filed as #521). Both must store what `source()` returned as an `AnyError`, and on a `Dyn(Error)` receiver that value's STATIC type has lost the `Error` trait — so a caller can follow one link and print it, but cannot store, re-erase, `downcast` or re-throw it. Spelling `Dyn(Error)` instead of `Dyn(SelfTrait)` is not available either: `Error` is unbound inside its own definition. So `source()` exists and works one level deep, and the walk over it does not. Freezing before that is decided would freeze a trait whose defining use case is still blocked. — stable modules only change additively; this one may still change.

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. What is missing is the part a real error story needs and this one does not have: ErrorChain and root_cause cannot be written today, and it is a compiler defect rather than a design gap (issues/self-trait-in-a-return-type-loses-the-trait-on-an-erased-receiver.md, filed as #521). Both must store what source() returned as an AnyError, and on a Dyn(Error) receiver that value's STATIC type has lost the Error trait — so a caller can follow one link and print it, but cannot store, re-erase, downcast or re-throw it. Spelling Dyn(Error) instead of Dyn(SelfTrait) is not available either: Error is unbound inside its own definition.

So source() exists and works one level deep, and the walk over it does not. Freezing before that is decided would freeze a trait whose defining use case is still blocked.

Types

AnyError type-alias
dyn(Error + ToString)

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(Error + ToString)

The error that caused it.

Trait Implementations

impl(generic(T : Type), where(T <: ToString), T : (ToString))
impl(generic(T : Type), where(T <: ToString), T : (ToString), Format)
format : fn(self : Self, spec : str) -> String

Render self under spec. An unrecognised spec degrades to the plain to_string() rendering rather than failing.

Parameters

NameTypeNotes
selfSelf
specstr

Returns: String

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

Wrap cause with message.

Parameters

NameTypeNotesDescription
messageString

What was being attempted.

causedyn(Error + ToString)

The error that caused it.

Returns: Context

impl(Context, ToString(...))
to_string : (Context) fn(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(self : Context) -> Option(dyn(Error + 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 is not expressible yet — the returned Dyn loses the Error trait on an erased receiver, so a caller can print one link but cannot follow it (#521, issues/self-trait-in-a-return-type-loses-the-trait-on-an-erased-receiver.md).

Parameters

NameTypeNotes
selfContext

Returns: Option(dyn(Error + 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
throwfn(generic(ResumeType) error : dyn(Error + ToString)) -> 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
IoExn struct
IoExn

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.

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(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 is not expressible yet — the returned Dyn loses the Error trait on an erased receiver, so a caller can print one link but cannot follow it (#521, issues/self-trait-in-a-return-type-loses-the-trait-on-an-erased-receiver.md).

Parameters

NameTypeNotes
selfSelf : (ToString)

Returns: Option(dyn( + ToString))

Implementors

Functions

error_is function
fn(err : AnyError, comptime(T) : Type) -> bool

True when the type-erased err is really a T — Rust's dyn Error::is.

A FREE function rather than a method because a blanket inherent method over E <: Error resolves on a Dyn(Error) receiver and then miscompiles: codegen treats every method call on a Dyn value as a trait method and emits a vtable indirection for a slot that does not exist. See issues/blanket-inherent-method-on-a-dyn-receiver-dispatches-through-the-vtable.md; when that is fixed this becomes err.is(T).

cond(
  error_is(err, NotFound) => recover(),
  true => rethrow(err)
);

To use the value and not just test for it, reach for the downcast(err, T) builtin this is written over — it returns Option(T).

Parameters

NameTypeNotes
errAnyError
TTypecomptime

Returns: bool