Skip to content

Examples

When making API calls to third-party services, we may want to enforce timeouts and retry mechanisms. In this example, the API call is set to retry a maximum of two times in case of failure, and the entire operation will be interrupted if it takes longer than 4 seconds.

import {
import Console
Console
,
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
} from "effect"
// Function to make the API call
const
const getJson: (url: string) => Effect.Effect<unknown, UnknownException, never>
getJson
= (
url: string
url
: string) =>
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const tryPromise: <unknown>(evaluate: (signal: AbortSignal) => PromiseLike<unknown>) => Effect.Effect<unknown, UnknownException, never> (+1 overload)

Creates an Effect that represents an asynchronous computation that might fail.

When to Use

In situations where you need to perform asynchronous operations that might fail, such as fetching data from an API, you can use the tryPromise constructor. This constructor is designed to handle operations that could throw exceptions by capturing those exceptions and transforming them into manageable errors.

Error Handling

There are two ways to handle errors with tryPromise:

  1. If you don't provide a catch function, the error is caught and the effect fails with an UnknownException.
  2. If you provide a catch function, the error is caught and the catch function maps it to an error of type E.

Interruptions

An optional AbortSignal can be provided to allow for interruption of the wrapped Promise API.

@seepromise if the effectful computation is asynchronous and does not throw errors.

@example

// Title: Fetching a TODO Item
import { Effect } from "effect"
const getTodo = (id: number) =>
// Will catch any errors and propagate them as UnknownException
Effect.tryPromise(() =>
fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
)
// ┌─── Effect<Response, UnknownException, never>
// ▼
const program = getTodo(1)

@example

// Title: Custom Error Handling import { Effect } from "effect"

const getTodo = (id: number) => Effect.tryPromise({ try: () => fetch(https://jsonplaceholder.typicode.com/todos/${id}), // remap the error catch: (unknown) => new Error(something went wrong ${unknown}) })

// ┌─── Effect<Response, Error, never> // ▼ const program = getTodo(1)

@since2.0.0

tryPromise
(() =>
function fetch(input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response>
fetch
(
url: string
url
).
Promise<Response>.then<unknown, never>(onfulfilled?: ((value: Response) => unknown) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<unknown>

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
((
res: Response
res
) => {
if (!
res: Response
res
.
Response.ok: boolean
ok
) {
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
("error")
throw new
var Error: ErrorConstructor
new (message?: string) => Error
Error
(
res: Response
res
.
Response.statusText: string
statusText
)
}
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
("ok")
return
res: Response
res
.
BodyMixin.json: () => Promise<unknown>
json
() as unknown
})
)
// Program that retries the API call twice,
// times out after 4 seconds, and logs errors
const
const program: (url: string) => Effect.Effect<unknown, never, never>
program
= (
url: string
url
: string) =>
const getJson: (url: string) => Effect.Effect<unknown, UnknownException, never>
getJson
(
url: string
url
).
Pipeable.pipe<Effect.Effect<unknown, UnknownException, never>, Effect.Effect<unknown, UnknownException, never>, Effect.Effect<unknown, UnknownException | TimeoutException, never>, Effect.Effect<...>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>, bc: (_: Effect.Effect<...>) => Effect.Effect<...>, cd: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const retry: <UnknownException, {
times: number;
}>(options: {
times: number;
}) => <A, R>(self: Effect.Effect<A, UnknownException, R>) => Effect.Effect<...> (+3 overloads)

Retries a failing effect based on a defined retry policy.

The retry function allows you to retry a failing effect multiple times according to a specified policy. This can be useful when dealing with intermittent failures, such as network issues or temporary resource unavailability. By defining a retry policy, you can control the number of retries, the delay between them, and when to stop retrying.

The retry function takes an effect and a policy, and will automatically retry the effect if it fails, following the rules of the policy. If the effect ultimately succeeds, the result will be returned. If the maximum retries are exhausted and the effect still fails, the failure is propagated.

@seeretryOrElse for a version that allows you to run a fallback.

@example

import { Effect, Schedule } from "effect"
let count = 0
// Simulates an effect with possible failures
const task = Effect.async<string, Error>((resume) => {
if (count <= 2) {
count++
console.log("failure")
resume(Effect.fail(new Error()))
} else {
console.log("success")
resume(Effect.succeed("yay!"))
}
})
// Define a repetition policy using a fixed delay between retries
const policy = Schedule.fixed("100 millis")
const repeated = Effect.retry(task, policy)
Effect.runPromise(repeated).then(console.log)
// Output:
// failure
// failure
// failure
// success
// yay!

@since2.0.0

retry
({
times: number
times
: 2 }),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const timeout: (duration: DurationInput) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E | TimeoutException, R> (+1 overload)

Adds a time limit to an effect, triggering a timeout if the effect exceeds the duration.

The timeout function allows you to specify a time limit for an effect's execution. If the effect does not complete within the given time, a TimeoutException is raised. This can be useful for controlling how long your program waits for a task to finish, ensuring that it doesn't hang indefinitely if the task takes too long.

@seetimeoutFail for a version that raises a custom error.

@seetimeoutFailCause for a version that raises a custom defect.

@seetimeoutTo for a version that allows specifying both success and timeout handlers.

@example

import { Effect } from "effect"
const task = Effect.gen(function* () {
console.log("Start processing...")
yield* Effect.sleep("2 seconds") // Simulates a delay in processing
console.log("Processing complete.")
return "Result"
})
// Output will show a TimeoutException as the task takes longer
// than the specified timeout duration
const timedEffect = task.pipe(Effect.timeout("1 second"))
Effect.runPromiseExit(timedEffect).then(console.log)
// Output:
// Start processing...
// {
// _id: 'Exit',
// _tag: 'Failure',
// cause: {
// _id: 'Cause',
// _tag: 'Fail',
// failure: { _tag: 'TimeoutException' }
// }
// }

@since2.0.0

timeout
("4 seconds"),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const catchAll: <any, void, never, never>(f: (e: any) => Effect.Effect<void, never, never>) => <A, R>(self: Effect.Effect<A, any, R>) => Effect.Effect<void | A, never, R> (+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
(
import Console
Console
.
const error: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

error
)
)
// Test the successful case
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runFork: <unknown, never>(effect: Effect.Effect<unknown, never, never>, options?: RunForkOptions) => RuntimeFiber<unknown, never>

The foundational function for running effects, returning a "fiber" that can be observed or interrupted.

When to Use

runFork is used to run an effect in the background by creating a fiber. It is the base function for all other run functions. It starts a fiber that can be observed or interrupted.

Unless you specifically need a Promise or synchronous operation, runFork is a good default choice.

@example

// Title: Running an Effect in the Background
import { Effect, Console, Schedule, Fiber } from "effect"
// ┌─── Effect<number, never, never>
// ▼
const program = Effect.repeat(
Console.log("running..."),
Schedule.spaced("200 millis")
)
// ┌─── RuntimeFiber<number, never>
// ▼
const fiber = Effect.runFork(program)
setTimeout(() => {
Effect.runFork(Fiber.interrupt(fiber))
}, 500)

@since2.0.0

runFork
(
const program: (url: string) => Effect.Effect<unknown, never, never>
program
("https://dummyjson.com/products/1?delay=1000"))
/*
Output:
ok
*/
// Test case: timeout scenario
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runFork: <unknown, never>(effect: Effect.Effect<unknown, never, never>, options?: RunForkOptions) => RuntimeFiber<unknown, never>

The foundational function for running effects, returning a "fiber" that can be observed or interrupted.

When to Use

runFork is used to run an effect in the background by creating a fiber. It is the base function for all other run functions. It starts a fiber that can be observed or interrupted.

Unless you specifically need a Promise or synchronous operation, runFork is a good default choice.

@example

// Title: Running an Effect in the Background
import { Effect, Console, Schedule, Fiber } from "effect"
// ┌─── Effect<number, never, never>
// ▼
const program = Effect.repeat(
Console.log("running..."),
Schedule.spaced("200 millis")
)
// ┌─── RuntimeFiber<number, never>
// ▼
const fiber = Effect.runFork(program)
setTimeout(() => {
Effect.runFork(Fiber.interrupt(fiber))
}, 500)

@since2.0.0

runFork
(
const program: (url: string) => Effect.Effect<unknown, never, never>
program
("https://dummyjson.com/products/1?delay=5000"))
/*
Output:
TimeoutException: Operation timed out before the specified duration of '4s' elapsed
*/
// Test case: API error handling
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runFork: <unknown, never>(effect: Effect.Effect<unknown, never, never>, options?: RunForkOptions) => RuntimeFiber<unknown, never>

The foundational function for running effects, returning a "fiber" that can be observed or interrupted.

When to Use

runFork is used to run an effect in the background by creating a fiber. It is the base function for all other run functions. It starts a fiber that can be observed or interrupted.

Unless you specifically need a Promise or synchronous operation, runFork is a good default choice.

@example

// Title: Running an Effect in the Background
import { Effect, Console, Schedule, Fiber } from "effect"
// ┌─── Effect<number, never, never>
// ▼
const program = Effect.repeat(
Console.log("running..."),
Schedule.spaced("200 millis")
)
// ┌─── RuntimeFiber<number, never>
// ▼
const fiber = Effect.runFork(program)
setTimeout(() => {
Effect.runFork(Fiber.interrupt(fiber))
}, 500)

@since2.0.0

runFork
(
const program: (url: string) => Effect.Effect<unknown, never, never>
program
("https://dummyjson.com/auth/products/1?delay=500"))
/*
Output:
error
error
error
UnknownException: An unknown error occurred
*/

Sometimes, we need to retry a failed API call only for specific error conditions, such as certain HTTP status codes.

import {
import Console
Console
,
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
} from "effect"
// Custom error class for handling status codes
class
class Err
Err
extends
var Error: ErrorConstructor
Error
{
constructor(
message: string
message
: string, readonly
Err.status: number
status
: number) {
super(
message: string
message
)
}
}
// Function to make the API call
const
const getJson: (url: string) => Effect.Effect<unknown, Err, never>
getJson
= (
url: string
url
: string) =>
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const tryPromise: <unknown, Err>(options: {
readonly try: (signal: AbortSignal) => PromiseLike<unknown>;
readonly catch: (error: unknown) => Err;
}) => Effect.Effect<unknown, Err, never> (+1 overload)

Creates an Effect that represents an asynchronous computation that might fail.

When to Use

In situations where you need to perform asynchronous operations that might fail, such as fetching data from an API, you can use the tryPromise constructor. This constructor is designed to handle operations that could throw exceptions by capturing those exceptions and transforming them into manageable errors.

Error Handling

There are two ways to handle errors with tryPromise:

  1. If you don't provide a catch function, the error is caught and the effect fails with an UnknownException.
  2. If you provide a catch function, the error is caught and the catch function maps it to an error of type E.

Interruptions

An optional AbortSignal can be provided to allow for interruption of the wrapped Promise API.

@seepromise if the effectful computation is asynchronous and does not throw errors.

@example

// Title: Fetching a TODO Item
import { Effect } from "effect"
const getTodo = (id: number) =>
// Will catch any errors and propagate them as UnknownException
Effect.tryPromise(() =>
fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
)
// ┌─── Effect<Response, UnknownException, never>
// ▼
const program = getTodo(1)

@example

// Title: Custom Error Handling import { Effect } from "effect"

const getTodo = (id: number) => Effect.tryPromise({ try: () => fetch(https://jsonplaceholder.typicode.com/todos/${id}), // remap the error catch: (unknown) => new Error(something went wrong ${unknown}) })

// ┌─── Effect<Response, Error, never> // ▼ const program = getTodo(1)

@since2.0.0

tryPromise
({
try: (signal: AbortSignal) => PromiseLike<unknown>
try
: () =>
function fetch(input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response>
fetch
(
url: string
url
).
Promise<Response>.then<unknown, never>(onfulfilled?: ((value: Response) => unknown) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<unknown>

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
((
res: Response
res
) => {
if (!
res: Response
res
.
Response.ok: boolean
ok
) {
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
(
res: Response
res
.
Response.status: number
status
)
throw new
constructor Err(message: string, status: number): Err
Err
(
res: Response
res
.
Response.statusText: string
statusText
,
res: Response
res
.
Response.status: number
status
)
}
return
res: Response
res
.
BodyMixin.json: () => Promise<unknown>
json
() as unknown
}),
catch: (error: unknown) => Err
catch
: (
e: unknown
e
) =>
e: unknown
e
as
class Err
Err
})
// Program that retries only for 401 status codes
const
const program: (url: string) => Effect.Effect<unknown, never, never>
program
= (
url: string
url
: string) =>
const getJson: (url: string) => Effect.Effect<unknown, Err, never>
getJson
(
url: string
url
).
Pipeable.pipe<Effect.Effect<unknown, Err, never>, Effect.Effect<unknown, Err, never>, Effect.Effect<unknown, never, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<unknown, Err, never>) => Effect.Effect<...>, bc: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const retry: <Err, {
while: (err: Err) => boolean;
}>(options: {
while: (err: Err) => boolean;
}) => <A, R>(self: Effect.Effect<A, Err, R>) => Effect.Effect<A, Err, R> (+3 overloads)

Retries a failing effect based on a defined retry policy.

The retry function allows you to retry a failing effect multiple times according to a specified policy. This can be useful when dealing with intermittent failures, such as network issues or temporary resource unavailability. By defining a retry policy, you can control the number of retries, the delay between them, and when to stop retrying.

The retry function takes an effect and a policy, and will automatically retry the effect if it fails, following the rules of the policy. If the effect ultimately succeeds, the result will be returned. If the maximum retries are exhausted and the effect still fails, the failure is propagated.

@seeretryOrElse for a version that allows you to run a fallback.

@example

import { Effect, Schedule } from "effect"
let count = 0
// Simulates an effect with possible failures
const task = Effect.async<string, Error>((resume) => {
if (count <= 2) {
count++
console.log("failure")
resume(Effect.fail(new Error()))
} else {
console.log("success")
resume(Effect.succeed("yay!"))
}
})
// Define a repetition policy using a fixed delay between retries
const policy = Schedule.fixed("100 millis")
const repeated = Effect.retry(task, policy)
Effect.runPromise(repeated).then(console.log)
// Output:
// failure
// failure
// failure
// success
// yay!

@since2.0.0

retry
({
while: (err: Err) => boolean
while
: (
err: Err
err
) =>
err: Err
err
.
Err.status: number
status
=== 401 }),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const catchAll: <any, void, never, never>(f: (e: any) => Effect.Effect<void, never, never>) => <A, R>(self: Effect.Effect<A, any, R>) => Effect.Effect<void | A, never, R> (+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
(
import Console
Console
.
const error: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

error
)
)
// Test the 401 scenario
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runFork: <unknown, never>(effect: Effect.Effect<unknown, never, never>, options?: RunForkOptions) => RuntimeFiber<unknown, never>

The foundational function for running effects, returning a "fiber" that can be observed or interrupted.

When to Use

runFork is used to run an effect in the background by creating a fiber. It is the base function for all other run functions. It starts a fiber that can be observed or interrupted.

Unless you specifically need a Promise or synchronous operation, runFork is a good default choice.

@example

// Title: Running an Effect in the Background
import { Effect, Console, Schedule, Fiber } from "effect"
// ┌─── Effect<number, never, never>
// ▼
const program = Effect.repeat(
Console.log("running..."),
Schedule.spaced("200 millis")
)
// ┌─── RuntimeFiber<number, never>
// ▼
const fiber = Effect.runFork(program)
setTimeout(() => {
Effect.runFork(Fiber.interrupt(fiber))
}, 500)

@since2.0.0

runFork
(
const program: (url: string) => Effect.Effect<unknown, never, never>
program
("https://dummyjson.com/auth/products/1?delay=1000")
)
/*
Output:
401
401
401
401
...
*/
// Test the 404 scenario
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runFork: <unknown, never>(effect: Effect.Effect<unknown, never, never>, options?: RunForkOptions) => RuntimeFiber<unknown, never>

The foundational function for running effects, returning a "fiber" that can be observed or interrupted.

When to Use

runFork is used to run an effect in the background by creating a fiber. It is the base function for all other run functions. It starts a fiber that can be observed or interrupted.

Unless you specifically need a Promise or synchronous operation, runFork is a good default choice.

@example

// Title: Running an Effect in the Background
import { Effect, Console, Schedule, Fiber } from "effect"
// ┌─── Effect<number, never, never>
// ▼
const program = Effect.repeat(
Console.log("running..."),
Schedule.spaced("200 millis")
)
// ┌─── RuntimeFiber<number, never>
// ▼
const fiber = Effect.runFork(program)
setTimeout(() => {
Effect.runFork(Fiber.interrupt(fiber))
}, 500)

@since2.0.0

runFork
(
const program: (url: string) => Effect.Effect<unknown, never, never>
program
("https://dummyjson.com/-"))
/*
Output:
404
Err [Error]: Not Found
*/

Sometimes, we need to run a task periodically until a longer-running task completes. This is common in scenarios like polling or periodic status logging.

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Console
Console
,
import Schedule
Schedule
} from "effect"
const
const longRunningEffect: Effect.Effect<void, never, never>
longRunningEffect
=
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
("done").
Pipeable.pipe<Effect.Effect<void, never, never>, Effect.Effect<void, never, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<void, never, never>) => Effect.Effect<void, never, never>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const delay: (duration: DurationInput) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R> (+1 overload)

Returns an effect that is delayed from this effect by the specified Duration.

@since2.0.0

delay
("5 seconds")
)
const
const action: Effect.Effect<void, never, never>
action
=
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
("action...")
const
const schedule: Schedule.Schedule<number, unknown, never>
schedule
=
import Schedule
Schedule
.
const fixed: (interval: DurationInput) => Schedule.Schedule<number>

A schedule that recurs on a fixed interval. Returns the number of repetitions of the schedule so far.

If the action run between updates takes longer than the interval, then the action will be run immediately, but re-runs will not "pile up".

|-----interval-----|-----interval-----|-----interval-----|
|---------action--------||action|-----|action|-----------|

@since2.0.0

fixed
("1.5 seconds")
const
const program: Effect.Effect<number | void, never, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const race: <number, never, never, void, never, never>(self: Effect.Effect<number, never, never>, that: Effect.Effect<void, never, never>) => Effect.Effect<number | void, never, never> (+1 overload)

Returns an effect that races this effect with the specified effect, returning the first successful A from the faster side. If one effect succeeds, the other will be interrupted. If neither succeeds, then the effect will fail with some error.

@since2.0.0

race
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const repeat: <void, never, never, number, never>(self: Effect.Effect<void, never, never>, schedule: Schedule.Schedule<number, void, never>) => Effect.Effect<number, never, never> (+3 overloads)

The repeat function returns a new effect that repeats the given effect according to a specified schedule or until the first failure. The scheduled recurrences are in addition to the initial execution, so repeat(action, Schedule.once) executes action once initially, and if it succeeds, repeats it an additional time.

@example

// Success Example
import { Effect, Schedule, Console } from "effect"
const action = Console.log("success")
const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis")
const program = Effect.repeat(action, policy)
Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))

@example

// Failure Example import { Effect, Schedule } from "effect"

let count = 0

// Define an async effect that simulates an action with possible failures const action = Effect.async<string, string>((resume) => { if (count > 1) { console.log("failure") resume(Effect.fail("Uh oh!")) } else { count++ console.log("success") resume(Effect.succeed("yay!")) } })

const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis") const program = Effect.repeat(action, policy)

Effect.runPromiseExit(program).then(console.log)

@since2.0.0

repeat
(
const action: Effect.Effect<void, never, never>
action
,
const schedule: Schedule.Schedule<number, unknown, never>
schedule
),
const longRunningEffect: Effect.Effect<void, never, never>
longRunningEffect
)
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

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

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 program: Effect.Effect<number | void, never, never>
program
)
/*
Output:
action...
action...
action...
action...
done
*/