Exit
Exit works in Effeck exactly as in Effect. Use Exit<A, E> to inspect success or an entire failure cause, including defects and interruption. A call that returns an Exit returns data; calling that data runs its recorded outcome.
Representing full outcomes
error ExportRejected {
reason: string
}
function inspectExport() {
const outcome = Effect.exit {
throw new ExportRejected({ reason: "empty selection" })
}
if (outcome.isFailure()) return outcome.cause.reasons.length
return 0
}An exit is Success with .value, or Failure with .cause. Effect.exit runs a program and returns that outcome as its success value. The caller can inspect it without re-raising the recorded failure.
Creating success and cause-based failure exits
function sampleOutcomes() {
const successful = Exit.succeed(12)
const failed = Exit.failCause(
Cause.fail("write rejected").combine(Cause.die(new Error("release failed")))
)
return { successful, failed }
}
function constantSuccess() {
return Exit.succeed(12)
}
// Exit.Exit<number>!!Exit.succeed and Exit.failCause construct exit data, including at a module's top level. Exit.succeed(12) gives a success exit containing 12, and Exit.failCause(cause) gives a failure exit containing the cause. Neither raises a failure. Use Effect.exit to run a program and capture its actual outcome instead.
Matching exit variants
function describe<A, E>(outcome: Exit.Exit<A, E>) {
return match (outcome) {
when Exit.Success(let value): `Completed: ${String(value)}`;
when Exit.Failure(let cause): Cause.pretty(cause);
}
}Exit.Success(let value) binds the success value, and Exit.Failure(let cause) binds the complete cause. Leaving out either arm is EK4701. Arms are ordinary expressions, so they can run Effect functions; outcome.match({ onSuccess, onFailure }) also works when the callbacks compute values synchronously. To test one variant, write outcome is Exit.Failure.
Relating exits to results
function asResult<A, E>(outcome: Exit.Exit<A, E>) {
if (outcome.isSuccess()) return Result.succeed(outcome.value)
return Result.fail(outcome.cause)
}
// Result.Result<A, Cause.Cause<E>>!!An exit carries roughly the same information as Result<A, Cause<E>>. A Result<A, E> alone cannot express the additional defect and interruption reasons. Keep the full cause when moving an execution outcome into another data structure.
Relating exits to effects
function replay<A, E>(outcome: Exit.Exit<A, E>) {
return outcome()
}
// A!E!Calling a held exit runs its constant outcome. Success returns the stored value; failure propagates the stored cause, without repeating the original work. Taking an exit with exit(program) and later calling it therefore separates inspection from propagation. Inside a try statement, finally (exit) binds the statement's own exit.
Coming from Effect
const outcome = Exit.succeed(value) still builds an exit object. Call outcome() to propagate it, or use Effect.exit(() => work()) to capture a program's outcome. Although Exit extends Effect, its constructors return data under the call rule.