TaskClass.prototype.orElse<F>(fn: (error: E) => TaskClass<T, F> | PromiseLike<T>): TaskClass<T, F>
The declared failure's second chance: on a declared E, run fn and adopt whatever it
produces — including its failure. Rust's Result::or_else, and the fallible twin of
TaskClass#unwrapOr.
Two-tier, like unwrapOr and unlike TaskClass#recover: a bug is not a planned
outcome and does not get a fallback. "Try the replica when the primary says NotFound" is a
plan; "try the replica when the primary threw a TypeError" is a way to ship the TypeError to
production twice.
The distinction from recover is the return type, and it is the whole point: recover
promises no declared failure remains (E becomes never), so its handler must not have one
to give. orElse keeps the channel open, so the fallback is allowed to fail and the caller
still has something to discriminate.
import { define, type Of } from '../result/failure.ts'; const NotFound = define('NotFound', (d: { id: number }) => `no user ${d.id}`); type NotFoundFailure = Of<typeof NotFound>; const fromPrimary = (id: number): Task<string, NotFoundFailure> => Task(() => { throw NotFound({ id }); }); const fromReplica = (id: number): Task<string, NotFoundFailure> => Task(() => `user ${id}`); // still a Task<string, NotFoundFailure> — the replica is allowed to miss too await fromPrimary(7).orElse(() => fromReplica(7)); // 'user 7'