Skip to content

Expected Errors

Expected errors are tracked at the type level by the Effect data type in the “Error channel”:

┌─── Represents the success type
│ ┌─── Represents the error type
│ │ ┌─── Represents required dependencies
▼ ▼ ▼
Effect<Success, Error, Requirements>

This means that the Effect type captures not only what the program returns on success but also what type of error it might produce.

Example (Creating an Effect That Can Fail)

In this example, we define a program that might randomly fail with an HttpError.

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Random
Random
} from "effect"
class
class HttpError
HttpError
{
readonly
HttpError._tag: "HttpError"
_tag
= "HttpError"
}
// ┌─── Effect<string, HttpError, never>
// ▼
const
const program: Effect.Effect<string, HttpError, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
// Generate a random number between 0 and 1
const
const n: number
n
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
// Simulate an HTTP error
if (
const n: number
n
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor HttpError(): HttpError
HttpError
())
}
return "some result"
})

The type of program tells us that it can either return a string or fail with an HttpError:

const program: Effect<string, HttpError, never>

In this case, we use a class to represent the HttpError type, which allows us to define both the error type and a constructor. However, you can use whatever you like to model your error types.

It’s also worth noting that we added a readonly _tag field to the class:

class HttpError {
// This field serves as a discriminant for the error
readonly _tag = "HttpError"
}

This discriminant field will be useful when we discuss APIs like Effect.catchTag, which help in handling specific error types.

In Effect, if a program can fail with multiple types of errors, they are automatically tracked as a union of those error types. This allows you to know exactly what errors can occur during execution, making error handling more precise and predictable.

The example below illustrates how errors are automatically tracked for you.

Example (Automatically Tracking Errors)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Random
Random
} from "effect"
class
class HttpError
HttpError
{
readonly
HttpError._tag: "HttpError"
_tag
= "HttpError"
}
class
class ValidationError
ValidationError
{
readonly
ValidationError._tag: "ValidationError"
_tag
= "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
// Generate two random numbers between 0 and 1
const
const n1: number
n1
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
const
const n2: number
n2
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
// Simulate an HTTP error
if (
const n1: number
n1
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor HttpError(): HttpError
HttpError
())
}
// Simulate a validation error
if (
const n2: number
n2
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor ValidationError(): ValidationError
ValidationError
())
}
return "some result"
})

Effect automatically keeps track of the possible errors that can occur during the execution of the program as a union:

const program: Effect<string, HttpError | ValidationError, never>

indicating that it can potentially fail with either a HttpError or a ValidationError.

When working with APIs like Effect.gen, Effect.map, Effect.flatMap, and Effect.andThen, it’s important to understand how they handle errors. These APIs are designed to short-circuit the execution upon encountering the first error.

What does this mean for you as a developer? Well, let’s say you have a chain of operations or a collection of effects to be executed in sequence. If any error occurs during the execution of one of these effects, the remaining computations will be skipped, and the error will be propagated to the final result.

In simpler terms, the short-circuiting behavior ensures that if something goes wrong at any step of your program, it won’t waste time executing unnecessary computations. Instead, it will immediately stop and return the error to let you know that something went wrong.

Example (Short-Circuiting Behavior)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Console
Console
} from "effect"
// Define three effects representing different tasks.
const
const task1: Effect.Effect<void, never, never>
task1
=
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
("Executing task1...")
const
const task2: Effect.Effect<never, string, never>
task2
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <string>(error: string) => Effect.Effect<never, string, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
("Something went wrong!")
const
const task3: Effect.Effect<void, never, never>
task3
=
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
("Executing task3...")
// Compose the three tasks to run them in sequence.
// If one of the tasks fails, the subsequent tasks won't be executed.
const
const program: Effect.Effect<void, string, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<void, never, never>> | YieldWrap<Effect.Effect<never, string, never>>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
yield*
const task1: Effect.Effect<void, never, never>
task1
// After task1, task2 is executed, but it fails with an error
yield*
const task2: Effect.Effect<never, string, never>
task2
// This computation won't be executed because the previous one fails
yield*
const task3: Effect.Effect<void, never, never>
task3
})
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runPromiseExit: <void, string>(effect: Effect.Effect<void, string, never>, options?: {
readonly signal?: AbortSignal;
} | undefined) => Promise<Exit<void, string>>

Runs an effect and returns a Promise that resolves to an Exit, which represents the outcome (success or failure) of the effect.

When to Use

Use runPromiseExit when you need to determine if an effect succeeded or failed, including any defects, and you want to work with a Promise.

Details

The Exit type represents the result of the effect:

  • If the effect succeeds, the result is wrapped in a Success.
  • If it fails, the failure information is provided as a Failure containing a Cause type.

@example

// Title: Handling Results as Exit
import { Effect } from "effect"
// Execute a successful effect and get the Exit result as a Promise
Effect.runPromiseExit(Effect.succeed(1)).then(console.log)
// Output:
// {
// _id: "Exit",
// _tag: "Success",
// value: 1
// }
// Execute a failing effect and get the Exit result as a Promise
Effect.runPromiseExit(Effect.fail("my error")).then(console.log)
// Output:
// {
// _id: "Exit",
// _tag: "Failure",
// cause: {
// _id: "Cause",
// _tag: "Fail",
// failure: "my error"
// }
// }

@since2.0.0

runPromiseExit
(
const program: Effect.Effect<void, string, never>
program
).
Promise<Exit<void, string>>.then<void, never>(onfulfilled?: ((value: Exit<void, string>) => void | PromiseLike<void>) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<...>

Attaches callbacks for the resolution and/or rejection of the Promise.

@paramonfulfilled The callback to execute when the Promise is resolved.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of which ever callback is executed.

then
(
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
globalThis.Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
)
/*
Output:
Executing task1...
{
_id: 'Exit',
_tag: 'Failure',
cause: { _id: 'Cause', _tag: 'Fail', failure: 'Something went wrong!' }
}
*/

This code snippet demonstrates the short-circuiting behavior when an error occurs. Each operation depends on the successful execution of the previous one. If any error occurs, the execution is short-circuited, and the error is propagated. In this specific example, task3 is never executed because an error occurs in task2.

The Effect.either function transforms an Effect<A, E, R> into an effect that encapsulates both potential failure and success within an Either data type:

Effect<A, E, R> -> Effect<Either<A, E>, never, R>

This means if you have an effect with the following type:

Effect<string, HttpError, never>

and you call Effect.either on it, the type becomes:

Effect<Either<string, HttpError>, never, never>

The resulting effect cannot fail because the potential failure is now represented within the Either’s Left type. The error type of the returned Effect is specified as never, confirming that the effect is structured to not fail.

By yielding an Either, we gain the ability to “pattern match” on this type to handle both failure and success cases within the generator function.

Example (Using Effect.either to Handle Errors)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Either

@since2.0.0

@since2.0.0

Either
,
import Random
Random
} from "effect"
class
class HttpError
HttpError
{
readonly
HttpError._tag: "HttpError"
_tag
= "HttpError"
}
class
class ValidationError
ValidationError
{
readonly
ValidationError._tag: "ValidationError"
_tag
= "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const n1: number
n1
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
const
const n2: number
n2
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
if (
const n1: number
n1
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor HttpError(): HttpError
HttpError
())
}
if (
const n2: number
n2
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor ValidationError(): ValidationError
ValidationError
())
}
return "some result"
})
// ┌─── Effect<string, never, never>
// ▼
const
const recovered: Effect.Effect<string, never, never>
recovered
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<Either.Either<string, HttpError | ValidationError>, never, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
// ┌─── Either<string, HttpError | ValidationError>
// ▼
const
const failureOrSuccess: Either.Either<string, HttpError | ValidationError>
failureOrSuccess
= yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const either: <string, HttpError | ValidationError, never>(self: Effect.Effect<string, HttpError | ValidationError, never>) => Effect.Effect<...>

Transforms an Effect into one that encapsulates both success and failure using the Either data type.

Details

either takes an effect that could potentially fail and converts it into an effect that always succeeds but with the result inside an Either. The Either can either be a Left (representing failure) or a Right (representing success). This allows you to handle both cases explicitly without causing the effect to fail.

The resulting effect cannot fail because failure is now represented inside the Either type.

@seeoption for a version that uses Option instead.

@seeexit for a version that uses Exit instead.

@example

import { Effect, Either, Random } from "effect"
class HttpError {
readonly _tag = "HttpError"
}
class ValidationError {
readonly _tag = "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const program = Effect.gen(function* () {
const n1 = yield* Random.next
const n2 = yield* Random.next
if (n1 < 0.5) {
yield* Effect.fail(new HttpError())
}
if (n2 < 0.5) {
yield* Effect.fail(new ValidationError())
}
return "some result"
})
// ┌─── Effect<string, never, never>
// ▼
const recovered = Effect.gen(function* () {
// ┌─── Either<string, HttpError | ValidationError>
// ▼
const failureOrSuccess = yield* Effect.either(program)
return Either.match(failureOrSuccess, {
onLeft: (error) => `Recovering from ${error._tag}`,
onRight: (value) => value // Do nothing in case of success
})
})

@since2.0.0

either
(
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
)
if (
import Either

@since2.0.0

@since2.0.0

Either
.
const isLeft: <string, HttpError | ValidationError>(self: Either.Either<string, HttpError | ValidationError>) => self is Either.Left<HttpError | ValidationError, string>

Determine if a Either is a Left.

@paramself - The Either to check.

@example

import { Either } from "effect"
assert.deepStrictEqual(Either.isLeft(Either.right(1)), false)
assert.deepStrictEqual(Either.isLeft(Either.left("a")), true)

@since2.0.0

isLeft
(
const failureOrSuccess: Either.Either<string, HttpError | ValidationError>
failureOrSuccess
)) {
// Failure case: you can extract the error from the `left` property
const
const error: HttpError | ValidationError
error
=
const failureOrSuccess: Either.Left<HttpError | ValidationError, string>
failureOrSuccess
.
Left<HttpError | ValidationError, string>.left: HttpError | ValidationError
left
return `Recovering from ${
const error: HttpError | ValidationError
error
.
_tag: "HttpError" | "ValidationError"
_tag
}`
} else {
// Success case: you can extract the value from the `right` property
return
const failureOrSuccess: Either.Right<HttpError | ValidationError, string>
failureOrSuccess
.
Right<HttpError | ValidationError, string>.right: string
right
}
})

As you can see since all errors are handled, the error type of the resulting effect recovered is never:

const recovered: Effect<string, never, never>

We can make the code less verbose by using the Either.match function, which directly accepts the two callback functions for handling errors and successful values:

Example (Simplifying with Either.match)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Either

@since2.0.0

@since2.0.0

Either
,
import Random
Random
} from "effect"
21 collapsed lines
class
class HttpError
HttpError
{
readonly
HttpError._tag: "HttpError"
_tag
= "HttpError"
}
class
class ValidationError
ValidationError
{
readonly
ValidationError._tag: "ValidationError"
_tag
= "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const n1: number
n1
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
const
const n2: number
n2
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
if (
const n1: number
n1
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor HttpError(): HttpError
HttpError
())
}
if (
const n2: number
n2
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor ValidationError(): ValidationError
ValidationError
())
}
return "some result"
})
// ┌─── Effect<string, never, never>
// ▼
const
const recovered: Effect.Effect<string, never, never>
recovered
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<Either.Either<string, HttpError | ValidationError>, never, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
// ┌─── Either<string, HttpError | ValidationError>
// ▼
const
const failureOrSuccess: Either.Either<string, HttpError | ValidationError>
failureOrSuccess
= yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const either: <string, HttpError | ValidationError, never>(self: Effect.Effect<string, HttpError | ValidationError, never>) => Effect.Effect<...>

Transforms an Effect into one that encapsulates both success and failure using the Either data type.

Details

either takes an effect that could potentially fail and converts it into an effect that always succeeds but with the result inside an Either. The Either can either be a Left (representing failure) or a Right (representing success). This allows you to handle both cases explicitly without causing the effect to fail.

The resulting effect cannot fail because failure is now represented inside the Either type.

@seeoption for a version that uses Option instead.

@seeexit for a version that uses Exit instead.

@example

import { Effect, Either, Random } from "effect"
class HttpError {
readonly _tag = "HttpError"
}
class ValidationError {
readonly _tag = "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const program = Effect.gen(function* () {
const n1 = yield* Random.next
const n2 = yield* Random.next
if (n1 < 0.5) {
yield* Effect.fail(new HttpError())
}
if (n2 < 0.5) {
yield* Effect.fail(new ValidationError())
}
return "some result"
})
// ┌─── Effect<string, never, never>
// ▼
const recovered = Effect.gen(function* () {
// ┌─── Either<string, HttpError | ValidationError>
// ▼
const failureOrSuccess = yield* Effect.either(program)
return Either.match(failureOrSuccess, {
onLeft: (error) => `Recovering from ${error._tag}`,
onRight: (value) => value // Do nothing in case of success
})
})

@since2.0.0

either
(
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
)
return
import Either

@since2.0.0

@since2.0.0

Either
.
const match: <string, HttpError | ValidationError, string, string>(self: Either.Either<string, HttpError | ValidationError>, options: {
...;
}) => string (+1 overload)

Takes two functions and an Either value, if the value is a Left the inner value is applied to the onLeft function, if the value is a Rightthe inner value is applied to theonRight` function.

@example

import { pipe, Either } from "effect"
const onLeft = (strings: ReadonlyArray<string>): string => `strings: ${strings.join(', ')}`
const onRight = (value: number): string => `Ok: ${value}`
assert.deepStrictEqual(pipe(Either.right(1), Either.match({ onLeft, onRight })), 'Ok: 1')
assert.deepStrictEqual(
pipe(Either.left(['string 1', 'string 2']), Either.match({ onLeft, onRight })),
'strings: string 1, string 2'
)

@since2.0.0

match
(
const failureOrSuccess: Either.Either<string, HttpError | ValidationError>
failureOrSuccess
, {
onLeft: (left: HttpError | ValidationError) => string
onLeft
: (
error: HttpError | ValidationError
error
) => `Recovering from ${
error: HttpError | ValidationError
error
.
_tag: "HttpError" | "ValidationError"
_tag
}`,
onRight: (right: string) => string
onRight
: (
value: string
value
) =>
value: string
value
// Do nothing in case of success
})
})

Transforms an effect to encapsulate both failure and success using the Option data type.

The Effect.option function wraps the success or failure of an effect within the Option type, making both cases explicit. If the original effect succeeds, its value is wrapped in Option.some. If it fails, the failure is mapped to Option.none.

The resulting effect cannot fail directly, as the error type is set to never. However, fatal errors like defects are not encapsulated.

Example (Using Effect.option to Handle Errors)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
} from "effect"
const
const maybe1: Effect.Effect<Option<number>, never, never>
maybe1
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const option: <number, never, never>(self: Effect.Effect<number, never, never>) => Effect.Effect<Option<number>, never, never>

Transforms an effect to encapsulate both failure and success using the Option data type.

Details

The option function wraps the success or failure of an effect within the Option type, making both cases explicit. If the original effect succeeds, its value is wrapped in Option.some. If it fails, the failure is mapped to Option.none.

The resulting effect cannot fail directly, as the error type is set to never. However, fatal errors like defects are not encapsulated.

@seeeither for a version that uses Either instead.

@seeexit for a version that uses Exit instead.

@example

// Title: Using Effect.option to Handle Errors
import { Effect } from "effect"
const maybe1 = Effect.option(Effect.succeed(1))
Effect.runPromiseExit(maybe1).then(console.log)
// Output:
// {
// _id: 'Exit',
// _tag: 'Success',
// value: { _id: 'Option', _tag: 'Some', value: 1 }
// }
const maybe2 = Effect.option(Effect.fail("Uh oh!"))
Effect.runPromiseExit(maybe2).then(console.log)
// Output:
// {
// _id: 'Exit',
// _tag: 'Success',
// value: { _id: 'Option', _tag: 'None' }
// }
const maybe3 = Effect.option(Effect.die("Boom!"))
Effect.runPromiseExit(maybe3).then(console.log)
// Output:
// {
// _id: 'Exit',
// _tag: 'Failure',
// cause: { _id: 'Cause', _tag: 'Die', defect: 'Boom!' }
// }

@since2.0.0

option
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const succeed: <number>(value: number) => Effect.Effect<number, never, never>

Creates an Effect that always succeeds with a given value.

When to Use

Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies.

@seefail to create an effect that represents a failure.

@example

// Title: Creating a Successful Effect
import { Effect } from "effect"
// Creating an effect that represents a successful scenario
//
// ┌─── Effect<number, never, never>
// ▼
const success = Effect.succeed(42)

@since2.0.0

succeed
(1))
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runPromiseExit: <Option<number>, never>(effect: Effect.Effect<Option<number>, never, never>, options?: {
readonly signal?: AbortSignal;
} | undefined) => Promise<Exit<...>>

Runs an effect and returns a Promise that resolves to an Exit, which represents the outcome (success or failure) of the effect.

When to Use

Use runPromiseExit when you need to determine if an effect succeeded or failed, including any defects, and you want to work with a Promise.

Details

The Exit type represents the result of the effect:

  • If the effect succeeds, the result is wrapped in a Success.
  • If it fails, the failure information is provided as a Failure containing a Cause type.

@example

// Title: Handling Results as Exit
import { Effect } from "effect"
// Execute a successful effect and get the Exit result as a Promise
Effect.runPromiseExit(Effect.succeed(1)).then(console.log)
// Output:
// {
// _id: "Exit",
// _tag: "Success",
// value: 1
// }
// Execute a failing effect and get the Exit result as a Promise
Effect.runPromiseExit(Effect.fail("my error")).then(console.log)
// Output:
// {
// _id: "Exit",
// _tag: "Failure",
// cause: {
// _id: "Cause",
// _tag: "Fail",
// failure: "my error"
// }
// }

@since2.0.0

runPromiseExit
(
const maybe1: Effect.Effect<Option<number>, never, never>
maybe1
).
Promise<Exit<Option<number>, never>>.then<void, never>(onfulfilled?: ((value: Exit<Option<number>, never>) => void | PromiseLike<void>) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<...>

Attaches callbacks for the resolution and/or rejection of the Promise.

@paramonfulfilled The callback to execute when the Promise is resolved.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of which ever callback is executed.

then
(
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
)
/*
Output:
{
_id: 'Exit',
_tag: 'Success',
value: { _id: 'Option', _tag: 'Some', value: 1 }
}
*/
const
const maybe2: Effect.Effect<Option<never>, never, never>
maybe2
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const option: <never, string, never>(self: Effect.Effect<never, string, never>) => Effect.Effect<Option<never>, never, never>

Transforms an effect to encapsulate both failure and success using the Option data type.

Details

The option function wraps the success or failure of an effect within the Option type, making both cases explicit. If the original effect succeeds, its value is wrapped in Option.some. If it fails, the failure is mapped to Option.none.

The resulting effect cannot fail directly, as the error type is set to never. However, fatal errors like defects are not encapsulated.

@seeeither for a version that uses Either instead.

@seeexit for a version that uses Exit instead.

@example

// Title: Using Effect.option to Handle Errors
import { Effect } from "effect"
const maybe1 = Effect.option(Effect.succeed(1))
Effect.runPromiseExit(maybe1).then(console.log)
// Output:
// {
// _id: 'Exit',
// _tag: 'Success',
// value: { _id: 'Option', _tag: 'Some', value: 1 }
// }
const maybe2 = Effect.option(Effect.fail("Uh oh!"))
Effect.runPromiseExit(maybe2).then(console.log)
// Output:
// {
// _id: 'Exit',
// _tag: 'Success',
// value: { _id: 'Option', _tag: 'None' }
// }
const maybe3 = Effect.option(Effect.die("Boom!"))
Effect.runPromiseExit(maybe3).then(console.log)
// Output:
// {
// _id: 'Exit',
// _tag: 'Failure',
// cause: { _id: 'Cause', _tag: 'Die', defect: 'Boom!' }
// }

@since2.0.0

option
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <string>(error: string) => Effect.Effect<never, string, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
("Uh oh!"))
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runPromiseExit: <Option<never>, never>(effect: Effect.Effect<Option<never>, never, never>, options?: {
readonly signal?: AbortSignal;
} | undefined) => Promise<Exit<Option<...>, never>>

Runs an effect and returns a Promise that resolves to an Exit, which represents the outcome (success or failure) of the effect.

When to Use

Use runPromiseExit when you need to determine if an effect succeeded or failed, including any defects, and you want to work with a Promise.

Details

The Exit type represents the result of the effect:

  • If the effect succeeds, the result is wrapped in a Success.
  • If it fails, the failure information is provided as a Failure containing a Cause type.

@example

// Title: Handling Results as Exit
import { Effect } from "effect"
// Execute a successful effect and get the Exit result as a Promise
Effect.runPromiseExit(Effect.succeed(1)).then(console.log)
// Output:
// {
// _id: "Exit",
// _tag: "Success",
// value: 1
// }
// Execute a failing effect and get the Exit result as a Promise
Effect.runPromiseExit(Effect.fail("my error")).then(console.log)
// Output:
// {
// _id: "Exit",
// _tag: "Failure",
// cause: {
// _id: "Cause",
// _tag: "Fail",
// failure: "my error"
// }
// }

@since2.0.0

runPromiseExit
(
const maybe2: Effect.Effect<Option<never>, never, never>
maybe2
).
Promise<Exit<Option<never>, never>>.then<void, never>(onfulfilled?: ((value: Exit<Option<never>, never>) => void | PromiseLike<void>) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<...>

Attaches callbacks for the resolution and/or rejection of the Promise.

@paramonfulfilled The callback to execute when the Promise is resolved.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of which ever callback is executed.

then
(
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
)
/*
Output:
{
_id: 'Exit',
_tag: 'Success',
value: { _id: 'Option', _tag: 'None' }
}
*/
const
const maybe3: Effect.Effect<Option<never>, never, never>
maybe3
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const option: <never, never, never>(self: Effect.Effect<never, never, never>) => Effect.Effect<Option<never>, never, never>

Transforms an effect to encapsulate both failure and success using the Option data type.

Details

The option function wraps the success or failure of an effect within the Option type, making both cases explicit. If the original effect succeeds, its value is wrapped in Option.some. If it fails, the failure is mapped to Option.none.

The resulting effect cannot fail directly, as the error type is set to never. However, fatal errors like defects are not encapsulated.

@seeeither for a version that uses Either instead.

@seeexit for a version that uses Exit instead.

@example

// Title: Using Effect.option to Handle Errors
import { Effect } from "effect"
const maybe1 = Effect.option(Effect.succeed(1))
Effect.runPromiseExit(maybe1).then(console.log)
// Output:
// {
// _id: 'Exit',
// _tag: 'Success',
// value: { _id: 'Option', _tag: 'Some', value: 1 }
// }
const maybe2 = Effect.option(Effect.fail("Uh oh!"))
Effect.runPromiseExit(maybe2).then(console.log)
// Output:
// {
// _id: 'Exit',
// _tag: 'Success',
// value: { _id: 'Option', _tag: 'None' }
// }
const maybe3 = Effect.option(Effect.die("Boom!"))
Effect.runPromiseExit(maybe3).then(console.log)
// Output:
// {
// _id: 'Exit',
// _tag: 'Failure',
// cause: { _id: 'Cause', _tag: 'Die', defect: 'Boom!' }
// }

@since2.0.0

option
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const die: (defect: unknown) => Effect.Effect<never>

Creates an effect that terminates a fiber with a specified error.

When to Use

Use die when encountering unexpected conditions in your code that should not be handled as regular errors but instead represent unrecoverable defects.

Details

The die function is used to signal a defect, which represents a critical and unexpected error in the code. When invoked, it produces an effect that does not handle the error and instead terminates the fiber.

The error channel of the resulting effect is of type never, indicating that it cannot recover from this failure.

@seedieSync for a variant that throws a specified error, evaluated lazily.

@seedieMessage for a variant that throws a RuntimeException with a message.

@example

// Title: Terminating on Division by Zero with a Specified Error
import { Effect } from "effect"
const divide = (a: number, b: number) =>
b === 0
? Effect.die(new Error("Cannot divide by zero"))
: Effect.succeed(a / b)
// ┌─── Effect<number, never, never>
// ▼
const program = divide(1, 0)
Effect.runPromise(program).catch(console.error)
// Output:
// (FiberFailure) Error: Cannot divide by zero
// ...stack trace...

@since2.0.0

die
("Boom!"))
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runPromiseExit: <Option<never>, never>(effect: Effect.Effect<Option<never>, never, never>, options?: {
readonly signal?: AbortSignal;
} | undefined) => Promise<Exit<Option<...>, never>>

Runs an effect and returns a Promise that resolves to an Exit, which represents the outcome (success or failure) of the effect.

When to Use

Use runPromiseExit when you need to determine if an effect succeeded or failed, including any defects, and you want to work with a Promise.

Details

The Exit type represents the result of the effect:

  • If the effect succeeds, the result is wrapped in a Success.
  • If it fails, the failure information is provided as a Failure containing a Cause type.

@example

// Title: Handling Results as Exit
import { Effect } from "effect"
// Execute a successful effect and get the Exit result as a Promise
Effect.runPromiseExit(Effect.succeed(1)).then(console.log)
// Output:
// {
// _id: "Exit",
// _tag: "Success",
// value: 1
// }
// Execute a failing effect and get the Exit result as a Promise
Effect.runPromiseExit(Effect.fail("my error")).then(console.log)
// Output:
// {
// _id: "Exit",
// _tag: "Failure",
// cause: {
// _id: "Cause",
// _tag: "Fail",
// failure: "my error"
// }
// }

@since2.0.0

runPromiseExit
(
const maybe3: Effect.Effect<Option<never>, never, never>
maybe3
).
Promise<Exit<Option<never>, never>>.then<void, never>(onfulfilled?: ((value: Exit<Option<never>, never>) => void | PromiseLike<void>) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<...>

Attaches callbacks for the resolution and/or rejection of the Promise.

@paramonfulfilled The callback to execute when the Promise is resolved.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of which ever callback is executed.

then
(
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
)
/*
Output:
{
_id: 'Exit',
_tag: 'Failure',
cause: { _id: 'Cause', _tag: 'Die', defect: 'Boom!' }
}
*/

Handles all errors in an effect by providing a fallback effect.

The Effect.catchAll function catches any errors that may occur during the execution of an effect and allows you to handle them by specifying a fallback effect. This ensures that the program continues without failing by recovering from errors using the provided fallback logic.

Example (Providing Recovery Logic for Recoverable Errors)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Random
Random
} from "effect"
class
class HttpError
HttpError
{
readonly
HttpError._tag: "HttpError"
_tag
= "HttpError"
}
class
class ValidationError
ValidationError
{
readonly
ValidationError._tag: "ValidationError"
_tag
= "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const n1: number
n1
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
const
const n2: number
n2
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
if (
const n1: number
n1
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor HttpError(): HttpError
HttpError
())
}
if (
const n2: number
n2
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor ValidationError(): ValidationError
ValidationError
())
}
return "some result"
})
// ┌─── Effect<string, never, never>
// ▼
const
const recovered: Effect.Effect<string, never, never>
recovered
=
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
.
Pipeable.pipe<Effect.Effect<string, HttpError | ValidationError, never>, Effect.Effect<string, never, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<string, HttpError | ValidationError, never>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const catchAll: <HttpError | ValidationError, string, never, never>(f: (e: HttpError | ValidationError) => Effect.Effect<string, never, never>) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Handles all errors in an effect by providing a fallback effect.

Details

The catchAll function catches any errors that may occur during the execution of an effect and allows you to handle them by specifying a fallback effect. This ensures that the program continues without failing by recovering from errors using the provided fallback logic.

Note: catchAll only handles recoverable errors. It will not recover from unrecoverable defects.

@seecatchAllCause for a version that can recover from both recoverable and unrecoverable errors.

@example

// Title: Providing Recovery Logic for Recoverable Errors
import { Effect, Random } from "effect"
class HttpError {
readonly _tag = "HttpError"
}
class ValidationError {
readonly _tag = "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const program = Effect.gen(function* () {
const n1 = yield* Random.next
const n2 = yield* Random.next
if (n1 < 0.5) {
yield* Effect.fail(new HttpError())
}
if (n2 < 0.5) {
yield* Effect.fail(new ValidationError())
}
return "some result"
})
// ┌─── Effect<string, never, never>
// ▼
const recovered = program.pipe(
Effect.catchAll((error) =>
Effect.succeed(`Recovering from ${error._tag}`)
)
)

@since2.0.0

catchAll
((
error: HttpError | ValidationError
error
) =>
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const succeed: <string>(value: string) => Effect.Effect<string, never, never>

Creates an Effect that always succeeds with a given value.

When to Use

Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies.

@seefail to create an effect that represents a failure.

@example

// Title: Creating a Successful Effect
import { Effect } from "effect"
// Creating an effect that represents a successful scenario
//
// ┌─── Effect<number, never, never>
// ▼
const success = Effect.succeed(42)

@since2.0.0

succeed
(`Recovering from ${
error: HttpError | ValidationError
error
.
_tag: "HttpError" | "ValidationError"
_tag
}`)
)
)

We can observe that the type in the error channel of our program has changed to never:

const recovered: Effect<string, never, never>

indicating that all errors have been handled.

Handles both recoverable and unrecoverable errors by providing a recovery effect.

The Effect.catchAllCause function allows you to handle all errors, including unrecoverable defects, by providing a recovery effect. The recovery logic is based on the Cause of the error, which provides detailed information about the failure.

Example (Recovering from All Errors)

import {
import Cause
Cause
,
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
} from "effect"
// Define an effect that may fail with a recoverable or unrecoverable error
const
const program: Effect.Effect<never, string, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <string>(error: string) => Effect.Effect<never, string, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
("Something went wrong!")
// Recover from all errors by examining the cause
const
const recovered: Effect.Effect<string, never, never>
recovered
=
const program: Effect.Effect<never, string, never>
program
.
Pipeable.pipe<Effect.Effect<never, string, never>, Effect.Effect<string, never, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<never, string, never>) => Effect.Effect<string, never, never>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const catchAllCause: <string, string, never, never>(f: (cause: Cause.Cause<string>) => Effect.Effect<string, never, never>) => <A, R>(self: Effect.Effect<A, string, R>) => Effect.Effect<...> (+1 overload)

Handles both recoverable and unrecoverable errors by providing a recovery effect.

When to Use

The catchAllCause function allows you to handle all errors, including unrecoverable defects, by providing a recovery effect. The recovery logic is based on the Cause of the error, which provides detailed information about the failure.

When to Recover from Defects

Defects are unexpected errors that typically shouldn't be recovered from, as they often indicate serious issues. However, in some cases, such as dynamically loaded plugins, controlled recovery might be needed.

@example

// Title: Recovering from All Errors
import { Cause, Effect } from "effect"
// Define an effect that may fail with a recoverable or unrecoverable error
const program = Effect.fail("Something went wrong!")
// Recover from all errors by examining the cause
const recovered = program.pipe(
Effect.catchAllCause((cause) =>
Cause.isFailType(cause)
? Effect.succeed("Recovered from a regular error")
: Effect.succeed("Recovered from a defect")
)
)
Effect.runPromise(recovered).then(console.log)
// Output: "Recovered from a regular error"

@since2.0.0

catchAllCause
((
cause: Cause.Cause<string>
cause
) =>
import Cause
Cause
.
const isFailType: <string>(self: Cause.Cause<string>) => self is Cause.Fail<string>

Returns true if the specified Cause is a Fail type, false otherwise.

@since2.0.0

isFailType
(
cause: Cause.Cause<string>
cause
)
?
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const succeed: <string>(value: string) => Effect.Effect<string, never, never>

Creates an Effect that always succeeds with a given value.

When to Use

Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies.

@seefail to create an effect that represents a failure.

@example

// Title: Creating a Successful Effect
import { Effect } from "effect"
// Creating an effect that represents a successful scenario
//
// ┌─── Effect<number, never, never>
// ▼
const success = Effect.succeed(42)

@since2.0.0

succeed
("Recovered from a regular error")
:
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const succeed: <string>(value: string) => Effect.Effect<string, never, never>

Creates an Effect that always succeeds with a given value.

When to Use

Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies.

@seefail to create an effect that represents a failure.

@example

// Title: Creating a Successful Effect
import { Effect } from "effect"
// Creating an effect that represents a successful scenario
//
// ┌─── Effect<number, never, never>
// ▼
const success = Effect.succeed(42)

@since2.0.0

succeed
("Recovered from a defect")
)
)
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runPromise: <string, never>(effect: Effect.Effect<string, never, never>, options?: {
readonly signal?: AbortSignal;
} | undefined) => Promise<string>

Executes an effect and returns the result as a Promise.

When to Use

Use runPromise when you need to execute an effect and work with the result using Promise syntax, typically for compatibility with other promise-based code.

If the effect succeeds, the promise will resolve with the result. If the effect fails, the promise will reject with an error.

@seerunPromiseExit for a version that returns an Exit type instead of rejecting.

@example

// Title: Running a Successful Effect as a Promise
import { Effect } from "effect"
Effect.runPromise(Effect.succeed(1)).then(console.log)
// Output: 1

@example

//Example: Handling a Failing Effect as a Rejected Promise import { Effect } from "effect"

Effect.runPromise(Effect.fail("my error")).catch(console.error) // Output: // (FiberFailure) Error: my error

@since2.0.0

runPromise
(
const recovered: Effect.Effect<string, never, never>
recovered
).
Promise<string>.then<void, never>(onfulfilled?: ((value: string) => void | PromiseLike<void>) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<...>

Attaches callbacks for the resolution and/or rejection of the Promise.

@paramonfulfilled The callback to execute when the Promise is resolved.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of which ever callback is executed.

then
(
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
)
// Output: "Recovered from a regular error"

The Effect.either function, which was previously shown as a way to catch all errors, can also be used to catch specific errors.

By yielding an Either, we gain the ability to “pattern match” on this type to handle both failure and success cases within the generator function.

Example (Handling Specific Errors with Effect.either)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Random
Random
,
import Either

@since2.0.0

@since2.0.0

Either
} from "effect"
class
class HttpError
HttpError
{
readonly
HttpError._tag: "HttpError"
_tag
= "HttpError"
}
class
class ValidationError
ValidationError
{
readonly
ValidationError._tag: "ValidationError"
_tag
= "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const n1: number
n1
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
const
const n2: number
n2
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
if (
const n1: number
n1
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor HttpError(): HttpError
HttpError
())
}
if (
const n2: number
n2
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor ValidationError(): ValidationError
ValidationError
())
}
return "some result"
})
// ┌─── Effect<string, ValidationError, never>
// ▼
const
const recovered: Effect.Effect<string, ValidationError, never>
recovered
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<never, ValidationError, never>> | YieldWrap<Effect.Effect<Either.Either<string, HttpError | ValidationError>, never, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const failureOrSuccess: Either.Either<string, HttpError | ValidationError>
failureOrSuccess
= yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const either: <string, HttpError | ValidationError, never>(self: Effect.Effect<string, HttpError | ValidationError, never>) => Effect.Effect<...>

Transforms an Effect into one that encapsulates both success and failure using the Either data type.

Details

either takes an effect that could potentially fail and converts it into an effect that always succeeds but with the result inside an Either. The Either can either be a Left (representing failure) or a Right (representing success). This allows you to handle both cases explicitly without causing the effect to fail.

The resulting effect cannot fail because failure is now represented inside the Either type.

@seeoption for a version that uses Option instead.

@seeexit for a version that uses Exit instead.

@example

import { Effect, Either, Random } from "effect"
class HttpError {
readonly _tag = "HttpError"
}
class ValidationError {
readonly _tag = "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const program = Effect.gen(function* () {
const n1 = yield* Random.next
const n2 = yield* Random.next
if (n1 < 0.5) {
yield* Effect.fail(new HttpError())
}
if (n2 < 0.5) {
yield* Effect.fail(new ValidationError())
}
return "some result"
})
// ┌─── Effect<string, never, never>
// ▼
const recovered = Effect.gen(function* () {
// ┌─── Either<string, HttpError | ValidationError>
// ▼
const failureOrSuccess = yield* Effect.either(program)
return Either.match(failureOrSuccess, {
onLeft: (error) => `Recovering from ${error._tag}`,
onRight: (value) => value // Do nothing in case of success
})
})

@since2.0.0

either
(
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
)
if (
import Either

@since2.0.0

@since2.0.0

Either
.
const isLeft: <string, HttpError | ValidationError>(self: Either.Either<string, HttpError | ValidationError>) => self is Either.Left<HttpError | ValidationError, string>

Determine if a Either is a Left.

@paramself - The Either to check.

@example

import { Either } from "effect"
assert.deepStrictEqual(Either.isLeft(Either.right(1)), false)
assert.deepStrictEqual(Either.isLeft(Either.left("a")), true)

@since2.0.0

isLeft
(
const failureOrSuccess: Either.Either<string, HttpError | ValidationError>
failureOrSuccess
)) {
const
const error: HttpError | ValidationError
error
=
const failureOrSuccess: Either.Left<HttpError | ValidationError, string>
failureOrSuccess
.
Left<HttpError | ValidationError, string>.left: HttpError | ValidationError
left
// Only handle HttpError errors
if (
const error: HttpError | ValidationError
error
.
_tag: "HttpError" | "ValidationError"
_tag
=== "HttpError") {
return "Recovering from HttpError"
} else {
// Rethrow ValidationError
return yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(
const error: ValidationError
error
)
}
} else {
return
const failureOrSuccess: Either.Right<HttpError | ValidationError, string>
failureOrSuccess
.
Right<HttpError | ValidationError, string>.right: string
right
}
})

We can observe that the type in the error channel of our program has changed to only show ValidationError:

const recovered: Effect<string, ValidationError, never>

indicating that HttpError has been handled.

If we also want to handle ValidationError, we can easily add another case to our code:

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Random
Random
,
import Either

@since2.0.0

@since2.0.0

Either
} from "effect"
19 collapsed lines
class
class HttpError
HttpError
{
readonly
HttpError._tag: "HttpError"
_tag
= "HttpError"
}
class
class ValidationError
ValidationError
{
readonly
ValidationError._tag: "ValidationError"
_tag
= "ValidationError"
}
const
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const n1: number
n1
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
const
const n2: number
n2
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
if (
const n1: number
n1
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor HttpError(): HttpError
HttpError
())
}
if (
const n2: number
n2
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor ValidationError(): ValidationError
ValidationError
())
}
return "some result"
})
// ┌─── Effect<string, never, never>
// ▼
const
const recovered: Effect.Effect<string, never, never>
recovered
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<Either.Either<string, HttpError | ValidationError>, never, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const failureOrSuccess: Either.Either<string, HttpError | ValidationError>
failureOrSuccess
= yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const either: <string, HttpError | ValidationError, never>(self: Effect.Effect<string, HttpError | ValidationError, never>) => Effect.Effect<...>

Transforms an Effect into one that encapsulates both success and failure using the Either data type.

Details

either takes an effect that could potentially fail and converts it into an effect that always succeeds but with the result inside an Either. The Either can either be a Left (representing failure) or a Right (representing success). This allows you to handle both cases explicitly without causing the effect to fail.

The resulting effect cannot fail because failure is now represented inside the Either type.

@seeoption for a version that uses Option instead.

@seeexit for a version that uses Exit instead.

@example

import { Effect, Either, Random } from "effect"
class HttpError {
readonly _tag = "HttpError"
}
class ValidationError {
readonly _tag = "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const program = Effect.gen(function* () {
const n1 = yield* Random.next
const n2 = yield* Random.next
if (n1 < 0.5) {
yield* Effect.fail(new HttpError())
}
if (n2 < 0.5) {
yield* Effect.fail(new ValidationError())
}
return "some result"
})
// ┌─── Effect<string, never, never>
// ▼
const recovered = Effect.gen(function* () {
// ┌─── Either<string, HttpError | ValidationError>
// ▼
const failureOrSuccess = yield* Effect.either(program)
return Either.match(failureOrSuccess, {
onLeft: (error) => `Recovering from ${error._tag}`,
onRight: (value) => value // Do nothing in case of success
})
})

@since2.0.0

either
(
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
)
if (
import Either

@since2.0.0

@since2.0.0

Either
.
const isLeft: <string, HttpError | ValidationError>(self: Either.Either<string, HttpError | ValidationError>) => self is Either.Left<HttpError | ValidationError, string>

Determine if a Either is a Left.

@paramself - The Either to check.

@example

import { Either } from "effect"
assert.deepStrictEqual(Either.isLeft(Either.right(1)), false)
assert.deepStrictEqual(Either.isLeft(Either.left("a")), true)

@since2.0.0

isLeft
(
const failureOrSuccess: Either.Either<string, HttpError | ValidationError>
failureOrSuccess
)) {
const
const error: HttpError | ValidationError
error
=
const failureOrSuccess: Either.Left<HttpError | ValidationError, string>
failureOrSuccess
.
Left<HttpError | ValidationError, string>.left: HttpError | ValidationError
left
// Handle both HttpError and ValidationError
if (
const error: HttpError | ValidationError
error
.
_tag: "HttpError" | "ValidationError"
_tag
=== "HttpError") {
return "Recovering from HttpError"
} else {
return "Recovering from ValidationError"
}
} else {
return
const failureOrSuccess: Either.Right<HttpError | ValidationError, string>
failureOrSuccess
.
Right<HttpError | ValidationError, string>.right: string
right
}
})

We can observe that the type in the error channel has changed to never:

const recovered: Effect<string, never, never>

indicating that all errors have been handled.

Catches and recovers from specific types of errors, allowing you to attempt recovery only for certain errors.

Effect.catchSome lets you selectively catch and handle errors of certain types by providing a recovery effect for specific errors. If the error matches a condition, recovery is attempted; if not, it doesn’t affect the program. This function doesn’t alter the error type, meaning the error type remains the same as in the original effect.

Example (Handling Specific Errors with Effect.catchSome)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Random
Random
,
import Option

@since2.0.0

@since2.0.0

Option
} from "effect"
class
class HttpError
HttpError
{
readonly
HttpError._tag: "HttpError"
_tag
= "HttpError"
}
class
class ValidationError
ValidationError
{
readonly
ValidationError._tag: "ValidationError"
_tag
= "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const n1: number
n1
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
const
const n2: number
n2
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
if (
const n1: number
n1
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor HttpError(): HttpError
HttpError
())
}
if (
const n2: number
n2
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor ValidationError(): ValidationError
ValidationError
())
}
return "some result"
})
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const
const recovered: Effect.Effect<string, HttpError | ValidationError, never>
recovered
=
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
.
Pipeable.pipe<Effect.Effect<string, HttpError | ValidationError, never>, Effect.Effect<string, HttpError | ValidationError, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const catchSome: <HttpError | ValidationError, string, never, never>(pf: (e: HttpError | ValidationError) => Option.Option<Effect.Effect<string, never, never>>) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Catches and recovers from specific types of errors, allowing you to attempt recovery only for certain errors.

Details

catchSome lets you selectively catch and handle errors of certain types by providing a recovery effect for specific errors. If the error matches a condition, recovery is attempted; if not, it doesn't affect the program. This function doesn't alter the error type, meaning the error type remains the same as in the original effect.

@seecatchIf for a version that allows you to recover from errors based on a predicate.

@example

// Title: Handling Specific Errors with Effect.catchSome
import { Effect, Random, Option } from "effect"
class HttpError {
readonly _tag = "HttpError"
}
class ValidationError {
readonly _tag = "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const program = Effect.gen(function* () {
const n1 = yield* Random.next
const n2 = yield* Random.next
if (n1 < 0.5) {
yield* Effect.fail(new HttpError())
}
if (n2 < 0.5) {
yield* Effect.fail(new ValidationError())
}
return "some result"
})
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const recovered = program.pipe(
Effect.catchSome((error) => {
// Only handle HttpError errors
if (error._tag === "HttpError") {
return Option.some(Effect.succeed("Recovering from HttpError"))
} else {
return Option.none()
}
})
)

@since2.0.0

catchSome
((
error: HttpError | ValidationError
error
) => {
// Only handle HttpError errors
if (
error: HttpError | ValidationError
error
.
_tag: "HttpError" | "ValidationError"
_tag
=== "HttpError") {
return
import Option

@since2.0.0

@since2.0.0

Option
.
const some: <Effect.Effect<string, never, never>>(value: Effect.Effect<string, never, never>) => Option.Option<Effect.Effect<string, never, never>>

Creates a new Option that wraps the given value.

@paramvalue - The value to wrap.

@since2.0.0

some
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const succeed: <string>(value: string) => Effect.Effect<string, never, never>

Creates an Effect that always succeeds with a given value.

When to Use

Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies.

@seefail to create an effect that represents a failure.

@example

// Title: Creating a Successful Effect
import { Effect } from "effect"
// Creating an effect that represents a successful scenario
//
// ┌─── Effect<number, never, never>
// ▼
const success = Effect.succeed(42)

@since2.0.0

succeed
("Recovering from HttpError"))
} else {
return
import Option

@since2.0.0

@since2.0.0

Option
.
const none: <never>() => Option.Option<never>

Creates a new Option that represents the absence of a value.

@since2.0.0

none
()
}
})
)

In the code above, Effect.catchSome takes a function that examines the error and decides whether to attempt recovery or not. If the error matches a specific condition, recovery can be attempted by returning Option.some(effect). If no recovery is possible, you can simply return Option.none().

It’s important to note that while Effect.catchSome lets you catch specific errors, it doesn’t alter the error type itself. Therefore, the resulting effect will still have the same error type as the original effect:

const recovered: Effect<string, HttpError | ValidationError, never>

Recovers from specific errors based on a predicate.

Effect.catchIf works similarly to Effect.catchSome, but it allows you to recover from errors by providing a predicate function. If the predicate matches the error, the recovery effect is applied. This function doesn’t alter the error type, so the resulting effect still carries the original error type unless a user-defined type guard is used to narrow the type.

Example (Catching Specific Errors with a Predicate)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Random
Random
} from "effect"
class
class HttpError
HttpError
{
readonly
HttpError._tag: "HttpError"
_tag
= "HttpError"
}
class
class ValidationError
ValidationError
{
readonly
ValidationError._tag: "ValidationError"
_tag
= "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const n1: number
n1
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
const
const n2: number
n2
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
if (
const n1: number
n1
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor HttpError(): HttpError
HttpError
())
}
if (
const n2: number
n2
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor ValidationError(): ValidationError
ValidationError
())
}
return "some result"
})
// ┌─── Effect<string, ValidationError, never>
// ▼
const
const recovered: Effect.Effect<string, ValidationError, never>
recovered
=
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
.
Pipeable.pipe<Effect.Effect<string, HttpError | ValidationError, never>, Effect.Effect<string, ValidationError, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const catchIf: <HttpError | ValidationError, HttpError, string, never, never>(refinement: Refinement<HttpError | ValidationError, HttpError>, f: (e: HttpError) => Effect.Effect<...>) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+3 overloads)

Recovers from specific errors based on a predicate.

When to Use

catchIf works similarly to

catchSome

, but it allows you to recover from errors by providing a predicate function. If the predicate matches the error, the recovery effect is applied. This function doesn't alter the error type, so the resulting effect still carries the original error type unless a user-defined type guard is used to narrow the type.

@example

// Title: Catching Specific Errors with a Predicate
import { Effect, Random } from "effect"
class HttpError {
readonly _tag = "HttpError"
}
class ValidationError {
readonly _tag = "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const program = Effect.gen(function* () {
const n1 = yield* Random.next
const n2 = yield* Random.next
if (n1 < 0.5) {
yield* Effect.fail(new HttpError())
}
if (n2 < 0.5) {
yield* Effect.fail(new ValidationError())
}
return "some result"
})
// ┌─── Effect<string, ValidationError, never>
// ▼
const recovered = program.pipe(
Effect.catchIf(
// Only handle HttpError errors
(error) => error._tag === "HttpError",
() => Effect.succeed("Recovering from HttpError")
)
)

@since2.0.0

catchIf
(
// Only handle HttpError errors
(
error: HttpError | ValidationError
error
) =>
error: HttpError | ValidationError
error
.
_tag: "HttpError" | "ValidationError"
_tag
=== "HttpError",
() =>
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const succeed: <string>(value: string) => Effect.Effect<string, never, never>

Creates an Effect that always succeeds with a given value.

When to Use

Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies.

@seefail to create an effect that represents a failure.

@example

// Title: Creating a Successful Effect
import { Effect } from "effect"
// Creating an effect that represents a successful scenario
//
// ┌─── Effect<number, never, never>
// ▼
const success = Effect.succeed(42)

@since2.0.0

succeed
("Recovering from HttpError")
)
)

It’s important to note that for TypeScript versions < 5.5, while Effect.catchIf lets you catch specific errors, it doesn’t alter the error type itself. Therefore, the resulting effect will still have the same error type as the original effect:

const recovered: Effect<string, HttpError | ValidationError, never>

In TypeScript versions >= 5.5, improved type narrowing causes the resulting error type to be inferred as ValidationError.

If you provide a user-defined type guard instead of a predicate, the resulting error type will be pruned, returning an Effect<string, ValidationError, never>:

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Random
Random
} from "effect"
21 collapsed lines
class
class HttpError
HttpError
{
readonly
HttpError._tag: "HttpError"
_tag
= "HttpError"
}
class
class ValidationError
ValidationError
{
readonly
ValidationError._tag: "ValidationError"
_tag
= "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const n1: number
n1
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
const
const n2: number
n2
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
if (
const n1: number
n1
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor HttpError(): HttpError
HttpError
())
}
if (
const n2: number
n2
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor ValidationError(): ValidationError
ValidationError
())
}
return "some result"
})
// ┌─── Effect<string, ValidationError, never>
// ▼
const
const recovered: Effect.Effect<string, ValidationError, never>
recovered
=
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
.
Pipeable.pipe<Effect.Effect<string, HttpError | ValidationError, never>, Effect.Effect<string, ValidationError, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const catchIf: <HttpError | ValidationError, HttpError, string, never, never>(refinement: Refinement<HttpError | ValidationError, HttpError>, f: (e: HttpError) => Effect.Effect<...>) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+3 overloads)

Recovers from specific errors based on a predicate.

When to Use

catchIf works similarly to

catchSome

, but it allows you to recover from errors by providing a predicate function. If the predicate matches the error, the recovery effect is applied. This function doesn't alter the error type, so the resulting effect still carries the original error type unless a user-defined type guard is used to narrow the type.

@example

// Title: Catching Specific Errors with a Predicate
import { Effect, Random } from "effect"
class HttpError {
readonly _tag = "HttpError"
}
class ValidationError {
readonly _tag = "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const program = Effect.gen(function* () {
const n1 = yield* Random.next
const n2 = yield* Random.next
if (n1 < 0.5) {
yield* Effect.fail(new HttpError())
}
if (n2 < 0.5) {
yield* Effect.fail(new ValidationError())
}
return "some result"
})
// ┌─── Effect<string, ValidationError, never>
// ▼
const recovered = program.pipe(
Effect.catchIf(
// Only handle HttpError errors
(error) => error._tag === "HttpError",
() => Effect.succeed("Recovering from HttpError")
)
)

@since2.0.0

catchIf
(
// User-defined type guard
(
error: HttpError | ValidationError
error
):
error: HttpError | ValidationError
error
is
class HttpError
HttpError
=>
error: HttpError | ValidationError
error
.
_tag: "HttpError" | "ValidationError"
_tag
=== "HttpError",
() =>
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const succeed: <string>(value: string) => Effect.Effect<string, never, never>

Creates an Effect that always succeeds with a given value.

When to Use

Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies.

@seefail to create an effect that represents a failure.

@example

// Title: Creating a Successful Effect
import { Effect } from "effect"
// Creating an effect that represents a successful scenario
//
// ┌─── Effect<number, never, never>
// ▼
const success = Effect.succeed(42)

@since2.0.0

succeed
("Recovering from HttpError")
)
)

Catches and handles specific errors by their _tag field, which is used as a discriminator.

Effect.catchTag is useful when your errors are tagged with a _tag field that identifies the error type. You can use this function to handle specific error types by matching the _tag value. This allows for precise error handling, ensuring that only specific errors are caught and handled.

The error type must have a _tag field to use Effect.catchTag. This field is used to identify and match errors.

Example (Handling Errors by Tag)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Random
Random
} from "effect"
class
class HttpError
HttpError
{
readonly
HttpError._tag: "HttpError"
_tag
= "HttpError"
}
class
class ValidationError
ValidationError
{
readonly
ValidationError._tag: "ValidationError"
_tag
= "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const n1: number
n1
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
const
const n2: number
n2
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
if (
const n1: number
n1
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor HttpError(): HttpError
HttpError
())
}
if (
const n2: number
n2
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor ValidationError(): ValidationError
ValidationError
())
}
return "some result"
})
// ┌─── Effect<string, ValidationError, never>
// ▼
const
const recovered: Effect.Effect<string, ValidationError, never>
recovered
=
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
.
Pipeable.pipe<Effect.Effect<string, HttpError | ValidationError, never>, Effect.Effect<string, ValidationError, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe
(
// Only handle HttpError errors
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const catchTag: <"HttpError", HttpError | ValidationError, string, never, never>(k: "HttpError", f: (e: HttpError) => Effect.Effect<string, never, never>) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Catches and handles specific errors by their _tag field, which is used as a discriminator.

When to Use

catchTag is useful when your errors are tagged with a readonly _tag field that identifies the error type. You can use this function to handle specific error types by matching the _tag value. This allows for precise error handling, ensuring that only specific errors are caught and handled.

The error type must have a readonly _tag field to use catchTag. This field is used to identify and match errors.

@seecatchTags for a version that allows you to handle multiple error types at once.

@example

// Title: Handling Errors by Tag
import { Effect, Random } from "effect"
class HttpError {
readonly _tag = "HttpError"
}
class ValidationError {
readonly _tag = "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const program = Effect.gen(function* () {
const n1 = yield* Random.next
const n2 = yield* Random.next
if (n1 < 0.5) {
yield* Effect.fail(new HttpError())
}
if (n2 < 0.5) {
yield* Effect.fail(new ValidationError())
}
return "some result"
})
// ┌─── Effect<string, ValidationError, never>
// ▼
const recovered = program.pipe(
// Only handle HttpError errors
Effect.catchTag("HttpError", (_HttpError) =>
Effect.succeed("Recovering from HttpError")
)
)

@since2.0.0

catchTag
("HttpError", (
_HttpError: HttpError
_HttpError
) =>
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const succeed: <string>(value: string) => Effect.Effect<string, never, never>

Creates an Effect that always succeeds with a given value.

When to Use

Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies.

@seefail to create an effect that represents a failure.

@example

// Title: Creating a Successful Effect
import { Effect } from "effect"
// Creating an effect that represents a successful scenario
//
// ┌─── Effect<number, never, never>
// ▼
const success = Effect.succeed(42)

@since2.0.0

succeed
("Recovering from HttpError")
)
)

In the example above, the Effect.catchTag function allows us to handle HttpError specifically. If a HttpError occurs during the execution of the program, the provided error handler function will be invoked, and the program will proceed with the recovery logic specified within the handler.

We can observe that the type in the error channel of our program has changed to only show ValidationError:

const recovered: Effect<string, ValidationError, never>

indicating that HttpError has been handled.

If we also wanted to handle ValidationError, we can simply add another catchTag:

Example (Handling Multiple Error Types with catchTag)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Random
Random
} from "effect"
21 collapsed lines
class
class HttpError
HttpError
{
readonly
HttpError._tag: "HttpError"
_tag
= "HttpError"
}
class
class ValidationError
ValidationError
{
readonly
ValidationError._tag: "ValidationError"
_tag
= "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const n1: number
n1
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
const
const n2: number
n2
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
if (
const n1: number
n1
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor HttpError(): HttpError
HttpError
())
}
if (
const n2: number
n2
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor ValidationError(): ValidationError
ValidationError
())
}
return "some result"
})
// ┌─── Effect<string, never, never>
// ▼
const
const recovered: Effect.Effect<string, never, never>
recovered
=
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
.
Pipeable.pipe<Effect.Effect<string, HttpError | ValidationError, never>, Effect.Effect<string, ValidationError, never>, Effect.Effect<...>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>, bc: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe
(
// Handle both HttpError and ValidationError
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const catchTag: <"HttpError", HttpError | ValidationError, string, never, never>(k: "HttpError", f: (e: HttpError) => Effect.Effect<string, never, never>) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Catches and handles specific errors by their _tag field, which is used as a discriminator.

When to Use

catchTag is useful when your errors are tagged with a readonly _tag field that identifies the error type. You can use this function to handle specific error types by matching the _tag value. This allows for precise error handling, ensuring that only specific errors are caught and handled.

The error type must have a readonly _tag field to use catchTag. This field is used to identify and match errors.

@seecatchTags for a version that allows you to handle multiple error types at once.

@example

// Title: Handling Errors by Tag
import { Effect, Random } from "effect"
class HttpError {
readonly _tag = "HttpError"
}
class ValidationError {
readonly _tag = "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const program = Effect.gen(function* () {
const n1 = yield* Random.next
const n2 = yield* Random.next
if (n1 < 0.5) {
yield* Effect.fail(new HttpError())
}
if (n2 < 0.5) {
yield* Effect.fail(new ValidationError())
}
return "some result"
})
// ┌─── Effect<string, ValidationError, never>
// ▼
const recovered = program.pipe(
// Only handle HttpError errors
Effect.catchTag("HttpError", (_HttpError) =>
Effect.succeed("Recovering from HttpError")
)
)

@since2.0.0

catchTag
("HttpError", (
_HttpError: HttpError
_HttpError
) =>
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const succeed: <string>(value: string) => Effect.Effect<string, never, never>

Creates an Effect that always succeeds with a given value.

When to Use

Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies.

@seefail to create an effect that represents a failure.

@example

// Title: Creating a Successful Effect
import { Effect } from "effect"
// Creating an effect that represents a successful scenario
//
// ┌─── Effect<number, never, never>
// ▼
const success = Effect.succeed(42)

@since2.0.0

succeed
("Recovering from HttpError")
),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const catchTag: <"ValidationError", ValidationError, string, never, never>(k: "ValidationError", f: (e: ValidationError) => Effect.Effect<string, never, never>) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Catches and handles specific errors by their _tag field, which is used as a discriminator.

When to Use

catchTag is useful when your errors are tagged with a readonly _tag field that identifies the error type. You can use this function to handle specific error types by matching the _tag value. This allows for precise error handling, ensuring that only specific errors are caught and handled.

The error type must have a readonly _tag field to use catchTag. This field is used to identify and match errors.

@seecatchTags for a version that allows you to handle multiple error types at once.

@example

// Title: Handling Errors by Tag
import { Effect, Random } from "effect"
class HttpError {
readonly _tag = "HttpError"
}
class ValidationError {
readonly _tag = "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const program = Effect.gen(function* () {
const n1 = yield* Random.next
const n2 = yield* Random.next
if (n1 < 0.5) {
yield* Effect.fail(new HttpError())
}
if (n2 < 0.5) {
yield* Effect.fail(new ValidationError())
}
return "some result"
})
// ┌─── Effect<string, ValidationError, never>
// ▼
const recovered = program.pipe(
// Only handle HttpError errors
Effect.catchTag("HttpError", (_HttpError) =>
Effect.succeed("Recovering from HttpError")
)
)

@since2.0.0

catchTag
("ValidationError", (
_ValidationError: ValidationError
_ValidationError
) =>
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const succeed: <string>(value: string) => Effect.Effect<string, never, never>

Creates an Effect that always succeeds with a given value.

When to Use

Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies.

@seefail to create an effect that represents a failure.

@example

// Title: Creating a Successful Effect
import { Effect } from "effect"
// Creating an effect that represents a successful scenario
//
// ┌─── Effect<number, never, never>
// ▼
const success = Effect.succeed(42)

@since2.0.0

succeed
("Recovering from ValidationError")
)
)

We can observe that the type in the error channel of our program has changed to never:

const recovered: Effect<string, never, never>

indicating that all errors have been handled.

Handles multiple errors in a single block of code using their _tag field.

Effect.catchTags is a convenient way to handle multiple error types at once. Instead of using Effect.catchTag multiple times, you can pass an object where each key is an error type’s _tag, and the value is the handler for that specific error. This allows you to catch and recover from multiple error types in a single call.

Example (Handling Multiple Tagged Error Types at Once)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Random
Random
} from "effect"
class
class HttpError
HttpError
{
readonly
HttpError._tag: "HttpError"
_tag
= "HttpError"
}
class
class ValidationError
ValidationError
{
readonly
ValidationError._tag: "ValidationError"
_tag
= "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

@example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const n1: number
n1
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
const
const n2: number
n2
= yield*
import Random
Random
.
const next: Effect.Effect<number, never, never>

Returns the next numeric value from the pseudo-random number generator.

@since2.0.0

next
if (
const n1: number
n1
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor HttpError(): HttpError
HttpError
())
}
if (
const n2: number
n2
< 0.5) {
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
(new
constructor ValidationError(): ValidationError
ValidationError
())
}
return "some result"
})
// ┌─── Effect<string, never, never>
// ▼
const
const recovered: Effect.Effect<string, never, never>
recovered
=
const program: Effect.Effect<string, HttpError | ValidationError, never>
program
.
Pipeable.pipe<Effect.Effect<string, HttpError | ValidationError, never>, Effect.Effect<string, never, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<string, HttpError | ValidationError, never>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const catchTags: <HttpError | ValidationError, {
HttpError: (_HttpError: HttpError) => Effect.Effect<string, never, never>;
ValidationError: (_ValidationError: ValidationError) => Effect.Effect<...>;
}>(cases: {
HttpError: (_HttpError: HttpError) => Effect.Effect<string, never, never>;
ValidationError: (_ValidationError: ValidationError) => Effect.Effect<...>;
}) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Handles multiple errors in a single block of code using their _tag field.

When to Use

catchTags is a convenient way to handle multiple error types at once. Instead of using

catchTag

multiple times, you can pass an object where each key is an error type's _tag, and the value is the handler for that specific error. This allows you to catch and recover from multiple error types in a single call.

The error type must have a readonly _tag field to use catchTag. This field is used to identify and match errors.

@example

// Title: Handling Multiple Tagged Error Types at Once
import { Effect, Random } from "effect"
class HttpError {
readonly _tag = "HttpError"
}
class ValidationError {
readonly _tag = "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const program = Effect.gen(function* () {
const n1 = yield* Random.next
const n2 = yield* Random.next
if (n1 < 0.5) {
yield* Effect.fail(new HttpError())
}
if (n2 < 0.5) {
yield* Effect.fail(new ValidationError())
}
return "some result"
})
// ┌─── Effect<string, never, never>
// ▼
const recovered = program.pipe(
Effect.catchTags({
HttpError: (_HttpError) =>
Effect.succeed(`Recovering from HttpError`),
ValidationError: (_ValidationError) =>
Effect.succeed(`Recovering from ValidationError`)
})
)

@since2.0.0

catchTags
({
type HttpError: (_HttpError: HttpError) => Effect.Effect<string, never, never>
HttpError
: (
_HttpError: HttpError
_HttpError
) =>
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const succeed: <string>(value: string) => Effect.Effect<string, never, never>

Creates an Effect that always succeeds with a given value.

When to Use

Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies.

@seefail to create an effect that represents a failure.

@example

// Title: Creating a Successful Effect
import { Effect } from "effect"
// Creating an effect that represents a successful scenario
//
// ┌─── Effect<number, never, never>
// ▼
const success = Effect.succeed(42)

@since2.0.0

succeed
(`Recovering from HttpError`),
type ValidationError: (_ValidationError: ValidationError) => Effect.Effect<string, never, never>
ValidationError
: (
_ValidationError: ValidationError
_ValidationError
) =>
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const succeed: <string>(value: string) => Effect.Effect<string, never, never>

Creates an Effect that always succeeds with a given value.

When to Use

Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies.

@seefail to create an effect that represents a failure.

@example

// Title: Creating a Successful Effect
import { Effect } from "effect"
// Creating an effect that represents a successful scenario
//
// ┌─── Effect<number, never, never>
// ▼
const success = Effect.succeed(42)

@since2.0.0

succeed
(`Recovering from ValidationError`)
})
)

This function takes an object where each property represents a specific error _tag ("HttpError" and "ValidationError" in this case), and the corresponding value is the error handler function to be executed when that particular error occurs.