Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Recovery Combinators — catch and Friends

The current Effect recovery surface works with typed errors E. Cause<E> appears in Exit and fibers, not in ordinary catch handlers.

catch

catch handles a typed failure by returning another effect.

let resilient = risky_db_call().catch(|error: DbError| {
    match error {
        DbError::NotFound => succeed(User::anonymous()),
        other => fail(other),
    }
});

Use catch when recovery itself may still fail.

catch_all

catch_all maps any typed error into a fallback success value. The returned effect is infallible through E.

let user = fetch_user(id).catch_all(|_error| User::anonymous());

Despite the name, this does not handle Cause::Die or Cause::Interrupt; it handles the effect’s typed error channel.

tap_error

tap_error runs an effect when the source fails, then re-emits the original error if the tap succeeds.

let observed = risky_call().tap_error(|message| log_error(message));

The handler receives a debug-formatted string because the original error is re-emitted without requiring Clone.

map_error

Use map_error to translate errors into your application error type.

let effect = db_call().map_error(AppError::Database);

Not Present Yet

The current API does not include fold, or_else, or ignore_error methods on Effect. Use catch, catch_all, map, and map_error, or pattern match on run_blocking(effect, env) at a boundary.