Skip to main content
The Exit module describes the result of executing an Effect workflow. An Exit<A, E> can be either a Success with value A or a Failure with a Cause<E>.

Type

type Exit<A, E = never> = Success<A, E> | Failure<A, E>
Represents the result of executing an Effect.
A
type parameter
The success value type
E
type parameter
default:"never"
The error type

Variants

Success

Represents a successful Effect execution.
interface Success<out A, out E> {
  readonly _tag: "Success"
  readonly value: A
}
value
A
The success value

Failure

Represents a failed Effect execution.
interface Failure<out A, out E> {
  readonly _tag: "Failure"
  readonly cause: Cause.Cause<E>
}
cause
Cause.Cause<E>
The cause of the failure

Constructors

succeed

Constructs a new Exit.Success.
const succeed: <A>(value: A) => Exit<A>
value
A
required
The success value
return
Exit<A>
An Exit representing success
import { Exit } from "effect"

const result = Exit.succeed(42)

fail

Constructs a new Exit.Failure from a recoverable error.
const fail: <E>(error: E) => Exit<never, E>
error
E
required
The error value
return
Exit<never, E>
An Exit representing failure
import { Exit } from "effect"

const result = Exit.fail("Something went wrong")

die

Constructs a new Exit.Failure from an unrecoverable defect.
const die: (defect: unknown) => Exit<never>
defect
unknown
required
The defect value
return
Exit<never>
An Exit representing a defect
import { Exit } from "effect"

const result = Exit.die(new Error("Unexpected error"))

failCause

Constructs a new Exit.Failure from a Cause.
const failCause: <E>(cause: Cause.Cause<E>) => Exit<never, E>
cause
Cause.Cause<E>
required
The cause of failure
return
Exit<never, E>
An Exit with the specified cause

interrupt

Constructs a new Exit.Failure indicating interruption.
const interrupt: (fiberId: FiberId.FiberId) => Exit<never>
fiberId
FiberId.FiberId
required
The ID of the interrupted fiber
return
Exit<never>
An Exit representing interruption

void

Represents an Exit which succeeds with undefined.
const void: Exit<void>
return
Exit<void>
An Exit succeeding with void

Refinements

isExit

Checks if a value is an Exit.
const isExit: (u: unknown) => u is Exit<unknown, unknown>
u
unknown
required
The value to check
return
boolean
true if the value is an Exit

isSuccess

Checks if an Exit is a Success.
const isSuccess: <A, E>(self: Exit<A, E>) => self is Success<A, E>
self
Exit<A, E>
required
The Exit to check
return
boolean
true if the Exit is a Success
import { Exit } from "effect"

const result = Exit.succeed(42)
Exit.isSuccess(result) // true

isFailure

Checks if an Exit is a Failure.
const isFailure: <A, E>(self: Exit<A, E>) => self is Failure<A, E>

isInterrupted

Checks if an Exit is a Failure due to interruption.
const isInterrupted: <A, E>(self: Exit<A, E>) => boolean

Getters

causeOption

Returns the Cause if the Exit is a Failure, None otherwise.
const causeOption: <A, E>(self: Exit<A, E>) => Option.Option<Cause.Cause<E>>
self
Exit<A, E>
required
The Exit to extract from
return
Option.Option<Cause.Cause<E>>
Some(cause) for Failure, None for Success
import { Exit, Option } from "effect"

const failure = Exit.fail("error")
const cause = Exit.causeOption(failure)
// Option.some(Cause.fail("error"))

getOrElse

Returns the success value or computes an alternate value.
const getOrElse: {
  <E, A2>(orElse: (cause: Cause.Cause<E>) => A2): <A>(self: Exit<A, E>) => A2 | A
  <A, E, A2>(self: Exit<A, E>, orElse: (cause: Cause.Cause<E>) => A2): A | A2
}
self
Exit<A, E>
required
The Exit to extract from
orElse
(cause: Cause.Cause<E>) => A2
required
Function to compute fallback value
return
A | A2
The success value or the computed fallback
import { Exit, Cause } from "effect"

const result = Exit.fail("error")
const value = Exit.getOrElse(result, (cause) => "fallback")
// "fallback"

Mapping

map

Maps over the success value.
const map: {
  <A, B>(f: (a: A) => B): <E>(self: Exit<A, E>) => Exit<B, E>
  <A, E, B>(self: Exit<A, E>, f: (a: A) => B): Exit<B, E>
}
self
Exit<A, E>
required
The Exit to map
f
(a: A) => B
required
The transformation function
return
Exit<B, E>
An Exit with the transformed success value
import { Exit } from "effect"

const result = Exit.succeed(5)
const mapped = Exit.map(result, (n) => n * 2)
// Exit.succeed(10)

mapError

Maps over the error value.
const mapError: {
  <E, E2>(f: (e: E) => E2): <A>(self: Exit<A, E>) => Exit<A, E2>
  <A, E, E2>(self: Exit<A, E>, f: (e: E) => E2): Exit<A, E2>
}

mapErrorCause

Maps over the Cause.
const mapErrorCause: {
  <E, E2>(f: (cause: Cause.Cause<E>) => Cause.Cause<E2>): <A>(self: Exit<A, E>) => Exit<A, E2>
  <E, A, E2>(self: Exit<A, E>, f: (cause: Cause.Cause<E>) => Cause.Cause<E2>): Exit<A, E2>
}

mapBoth

Maps over both success and failure.
const mapBoth: {
  <E, A, E2, A2>(options: {
    readonly onFailure: (e: E) => E2
    readonly onSuccess: (a: A) => A2
  }): (self: Exit<A, E>) => Exit<A2, E2>
  <A, E, E2, A2>(self: Exit<A, E>, options: {
    readonly onFailure: (e: E) => E2
    readonly onSuccess: (a: A) => A2
  }): Exit<A2, E2>
}

Matching

match

Pattern matches on an Exit.
const match: {
  <E, A, Z1, Z2>(options: {
    readonly onFailure: (cause: Cause.Cause<E>) => Z1
    readonly onSuccess: (a: A) => Z2
  }): (self: Exit<A, E>) => Z1 | Z2
  <A, E, Z1, Z2>(self: Exit<A, E>, options: {
    readonly onFailure: (cause: Cause.Cause<E>) => Z1
    readonly onSuccess: (a: A) => Z2
  }): Z1 | Z2
}
self
Exit<A, E>
required
The Exit to match on
options.onSuccess
(a: A) => Z2
required
Handler for Success case
options.onFailure
(cause: Cause.Cause<E>) => Z1
required
Handler for Failure case
return
Z1 | Z2
The result of the appropriate handler
import { Exit } from "effect"

const result = Exit.succeed(42)

const message = Exit.match(result, {
  onSuccess: (value) => `Success: ${value}`,
  onFailure: (cause) => `Failure: ${cause}`
})
// "Success: 42"

matchEffect

Pattern matches with effectful handlers.
const matchEffect: {
  <E, A2, E2, R, A, A3, E3, R2>(options: {
    readonly onFailure: (cause: Cause.Cause<E>) => Effect.Effect<A2, E2, R>
    readonly onSuccess: (a: A) => Effect.Effect<A3, E3, R2>
  }): (self: Exit<A, E>) => Effect.Effect<A2 | A3, E2 | E3, R | R2>
  ...
}

Sequencing

flatMap

Sequentially composes Exits.
const flatMap: {
  <A, A2, E2>(f: (a: A) => Exit<A2, E2>): <E>(self: Exit<A, E>) => Exit<A2, E2 | E>
  <A, E, E2, A2>(self: Exit<A, E>, f: (a: A) => Exit<A2, E2>): Exit<A2, E | E2>
}

flatten

Flattens a nested Exit.
const flatten: <A, E, E2>(self: Exit<Exit<A, E>, E2>) => Exit<A, E | E2>

Zipping

zip

Sequentially zips two Exits.
const zip: {
  <A2, E2>(that: Exit<A2, E2>): <A, E>(self: Exit<A, E>) => Exit<[A, A2], E2 | E>
  <A, E, A2, E2>(self: Exit<A, E>, that: Exit<A2, E2>): Exit<[A, A2], E | E2>
}
self
Exit<A, E>
required
The first Exit
that
Exit<A2, E2>
required
The second Exit
return
Exit<[A, A2], E | E2>
An Exit with a tuple of both values, or the first failure
import { Exit } from "effect"

const exit1 = Exit.succeed(1)
const exit2 = Exit.succeed("hello")
const zipped = Exit.zip(exit1, exit2)
// Exit.succeed([1, "hello"])

zipPar

Parallelly zips two Exits.
const zipPar: {
  <A2, E2>(that: Exit<A2, E2>): <A, E>(self: Exit<A, E>) => Exit<[A, A2], E2 | E>
  <A, E, A2, E2>(self: Exit<A, E>, that: Exit<A2, E2>): Exit<[A, A2], E | E2>
}
The difference between zip and zipPar is how they combine errors - zipPar combines failures in parallel.

Conversions

fromEither

Converts an Either into an Exit.
const fromEither: <R, L>(either: Either.Either<R, L>) => Exit<R, L>
either
Either.Either<R, L>
required
The Either to convert
return
Exit<R, L>
An Exit representation

fromOption

Converts an Option into an Exit.
const fromOption: <A>(option: Option.Option<A>) => Exit<A, void>

Build docs developers (and LLMs) love