Skip to content

Matching

In the Effect module, similar to other modules like Option and Exit, we have a Effect.match function that allows us to handle different cases simultaneously. Additionally, Effect provides various functions to manage both success and failure scenarios in effectful programs.

Effect.match lets you define custom handlers for both success and failure scenarios. You provide separate functions to handle each case, allowing you to process the result if the effect succeeds, or handle the error if the effect fails.

This is useful for structuring your code to respond differently to success or failure without triggering side effects.

Example (Handling Both Success and Failure Cases)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
} from "effect"
const
const success: Effect.Effect<number, Error, never>
success
:
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
interface Effect<out A, out E = never, out R = never>

The Effect interface defines a value that describes a workflow or job, which can succeed or fail.

Details

The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management.

To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.

@since2.0.0

@since2.0.0

Effect
<number,
interface Error
Error
> =
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
(42)
const
const program1: Effect.Effect<string, never, never>
program1
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const match: <number, Error, never, string, string>(self: Effect.Effect<number, Error, never>, options: {
readonly onFailure: (error: Error) => string;
readonly onSuccess: (value: number) => string;
}) => Effect.Effect<...> (+1 overload)

Handles both success and failure cases of an effect without performing side effects.

Details

match lets you define custom handlers for both success and failure scenarios. You provide separate functions to handle each case, allowing you to process the result if the effect succeeds, or handle the error if the effect fails.

When to Use

This is useful for structuring your code to respond differently to success or failure without triggering side effects.

@seematchEffect if you need to perform side effects in the handlers.

@example

// Title: Handling Both Success and Failure Cases
import { Effect } from "effect"
const success: Effect.Effect<number, Error> = Effect.succeed(42)
const program1 = Effect.match(success, {
onFailure: (error) => `failure: ${error.message}`,
onSuccess: (value) => `success: ${value}`
})
// Run and log the result of the successful effect
Effect.runPromise(program1).then(console.log)
// Output: "success: 42"
const failure: Effect.Effect<number, Error> = Effect.fail(
new Error("Uh oh!")
)
const program2 = Effect.match(failure, {
onFailure: (error) => `failure: ${error.message}`,
onSuccess: (value) => `success: ${value}`
})
// Run and log the result of the failed effect
Effect.runPromise(program2).then(console.log)
// Output: "failure: Uh oh!"

@since2.0.0

match
(
const success: Effect.Effect<number, Error, never>
success
, {
onFailure: (error: Error) => string
onFailure
: (
error: Error
error
) => `failure: ${
error: Error
error
.
Error.message: string
message
}`,
onSuccess: (value: number) => string
onSuccess
: (
value: number
value
) => `success: ${
value: number
value
}`
})
// Run and log the result of the successful effect
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 program1: Effect.Effect<string, never, never>
program1
).
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: "success: 42"
const
const failure: Effect.Effect<number, Error, never>
failure
:
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
interface Effect<out A, out E = never, out R = never>

The Effect interface defines a value that describes a workflow or job, which can succeed or fail.

Details

The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management.

To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.

@since2.0.0

@since2.0.0

Effect
<number,
interface Error
Error
> =
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <Error>(error: Error) => Effect.Effect<never, Error, 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
var Error: ErrorConstructor
new (message?: string) => Error
Error
("Uh oh!")
)
const
const program2: Effect.Effect<string, never, never>
program2
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const match: <number, Error, never, string, string>(self: Effect.Effect<number, Error, never>, options: {
readonly onFailure: (error: Error) => string;
readonly onSuccess: (value: number) => string;
}) => Effect.Effect<...> (+1 overload)

Handles both success and failure cases of an effect without performing side effects.

Details

match lets you define custom handlers for both success and failure scenarios. You provide separate functions to handle each case, allowing you to process the result if the effect succeeds, or handle the error if the effect fails.

When to Use

This is useful for structuring your code to respond differently to success or failure without triggering side effects.

@seematchEffect if you need to perform side effects in the handlers.

@example

// Title: Handling Both Success and Failure Cases
import { Effect } from "effect"
const success: Effect.Effect<number, Error> = Effect.succeed(42)
const program1 = Effect.match(success, {
onFailure: (error) => `failure: ${error.message}`,
onSuccess: (value) => `success: ${value}`
})
// Run and log the result of the successful effect
Effect.runPromise(program1).then(console.log)
// Output: "success: 42"
const failure: Effect.Effect<number, Error> = Effect.fail(
new Error("Uh oh!")
)
const program2 = Effect.match(failure, {
onFailure: (error) => `failure: ${error.message}`,
onSuccess: (value) => `success: ${value}`
})
// Run and log the result of the failed effect
Effect.runPromise(program2).then(console.log)
// Output: "failure: Uh oh!"

@since2.0.0

match
(
const failure: Effect.Effect<number, Error, never>
failure
, {
onFailure: (error: Error) => string
onFailure
: (
error: Error
error
) => `failure: ${
error: Error
error
.
Error.message: string
message
}`,
onSuccess: (value: number) => string
onSuccess
: (
value: number
value
) => `success: ${
value: number
value
}`
})
// Run and log the result of the failed effect
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 program2: Effect.Effect<string, never, never>
program2
).
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: "failure: Uh oh!"

Effect.ignore allows you to run an effect without caring about its result, whether it succeeds or fails.

This is useful when you only care about the side effects of the effect and do not need to handle or process its outcome.

Example (Using Effect.ignore to Discard Values)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
} from "effect"
// ┌─── Effect<number, string, never>
// ▼
const
const task: Effect.Effect<number, string, never>
task
=
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!").
Pipeable.pipe<Effect.Effect<never, string, never>, Effect.Effect<number, string, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<never, string, never>) => Effect.Effect<number, string, never>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const as: <number>(value: number) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<number, E, R> (+1 overload)

Replaces the value inside an effect with a constant value.

as allows you to ignore the original value inside an effect and replace it with a new constant value.

@example

// Title: Replacing a Value
import { pipe, Effect } from "effect"
// Replaces the value 5 with the constant "new value"
const program = pipe(Effect.succeed(5), Effect.as("new value"))
Effect.runPromise(program).then(console.log)
// Output: "new value"

@since2.0.0

as
(5))
// ┌─── Effect<void, never, never>
// ▼
const
const program: Effect.Effect<void, never, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const ignore: <number, string, never>(self: Effect.Effect<number, string, never>) => Effect.Effect<void, never, never>

Discards both the success and failure values of an effect.

When to Use

ignore allows you to run an effect without caring about its result, whether it succeeds or fails. This is useful when you only care about the side effects of the effect and do not need to handle or process its outcome.

@example

// Title: Using Effect.ignore to Discard Values
import { Effect } from "effect"
// ┌─── Effect<number, string, never>
// ▼
const task = Effect.fail("Uh oh!").pipe(Effect.as(5))
// ┌─── Effect<void, never, never>
// ▼
const program = Effect.ignore(task)

@since2.0.0

ignore
(
const task: Effect.Effect<number, string, never>
task
)

The Effect.matchEffect function is similar to Effect.match, but it enables you to perform side effects in the handlers for both success and failure outcomes.

This is useful when you need to execute additional actions, like logging or notifying users, based on whether an effect succeeds or fails.

Example (Handling Success and Failure with Side Effects)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
} from "effect"
const
const success: Effect.Effect<number, Error, never>
success
:
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
interface Effect<out A, out E = never, out R = never>

The Effect interface defines a value that describes a workflow or job, which can succeed or fail.

Details

The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management.

To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.

@since2.0.0

@since2.0.0

Effect
<number,
interface Error
Error
> =
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
(42)
const
const failure: Effect.Effect<number, Error, never>
failure
:
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
interface Effect<out A, out E = never, out R = never>

The Effect interface defines a value that describes a workflow or job, which can succeed or fail.

Details

The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management.

To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.

@since2.0.0

@since2.0.0

Effect
<number,
interface Error
Error
> =
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <Error>(error: Error) => Effect.Effect<never, Error, 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
var Error: ErrorConstructor
new (message?: string) => Error
Error
("Uh oh!")
)
const
const program1: Effect.Effect<string, never, never>
program1
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const matchEffect: <number, Error, never, string, never, never, string, never, never>(self: Effect.Effect<number, Error, never>, options: {
readonly onFailure: (e: Error) => Effect.Effect<string, never, never>;
readonly onSuccess: (a: number) => Effect.Effect<...>;
}) => Effect.Effect<...> (+1 overload)

Handles both success and failure cases of an effect, allowing for additional side effects.

Details

The matchEffect function is similar to

match

, but it enables you to perform side effects in the handlers for both success and failure outcomes.

When to Use

This is useful when you need to execute additional actions, like logging or notifying users, based on whether an effect succeeds or fails.

@seematch if you don't need side effects and only want to handle the result or failure.

@example

// Title: Handling Both Success and Failure Cases with Side Effects
import { Effect } from "effect"
const success: Effect.Effect<number, Error> = Effect.succeed(42)
const failure: Effect.Effect<number, Error> = Effect.fail(
new Error("Uh oh!")
)
const program1 = Effect.matchEffect(success, {
onFailure: (error) =>
Effect.succeed(`failure: ${error.message}`).pipe(
Effect.tap(Effect.log)
),
onSuccess: (value) =>
Effect.succeed(`success: ${value}`).pipe(Effect.tap(Effect.log))
})
console.log(Effect.runSync(program1))
// Output:
// timestamp=... level=INFO fiber=#0 message="success: 42"
// success: 42
const program2 = Effect.matchEffect(failure, {
onFailure: (error) =>
Effect.succeed(`failure: ${error.message}`).pipe(
Effect.tap(Effect.log)
),
onSuccess: (value) =>
Effect.succeed(`success: ${value}`).pipe(Effect.tap(Effect.log))
})
console.log(Effect.runSync(program2))
// Output:
// timestamp=... level=INFO fiber=#1 message="failure: Uh oh!"
// failure: Uh oh!

@since2.0.0

matchEffect
(
const success: Effect.Effect<number, Error, never>
success
, {
onFailure: (e: Error) => Effect.Effect<string, never, never>
onFailure
: (
error: Error
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
(`failure: ${
error: Error
error
.
Error.message: string
message
}`).
Pipeable.pipe<Effect.Effect<string, never, never>, Effect.Effect<string, never, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<string, never, never>) => Effect.Effect<string, never, never>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const tap: <string, Effect.Effect<void, never, never>>(f: (a: string) => Effect.Effect<void, never, never>) => <E, R>(self: Effect.Effect<string, E, R>) => Effect.Effect<...> (+7 overloads)

Runs a side effect with the result of an effect without changing the original value.

When to Use

Use tap when you want to perform a side effect, like logging or tracking, without modifying the main value. This is useful when you need to observe or record an action but want the original value to be passed to the next step.

Details

tap works similarly to flatMap, but it ignores the result of the function passed to it. The value from the previous effect remains available for the next part of the chain. Note that if the side effect fails, the entire chain will fail too.

@example

// Title: Logging a step in a pipeline
import { Console, Effect, pipe } from "effect"
// Function to apply a discount safely to a transaction amount
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)
// Simulated asynchronous task to fetch a transaction amount from database
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const finalAmount = pipe(
fetchTransactionAmount,
// Log the fetched transaction amount
Effect.tap((amount) => Console.log(`Apply a discount to: ${amount}`)),
// `amount` is still available!
Effect.flatMap((amount) => applyDiscount(amount, 5))
)
Effect.runPromise(finalAmount).then(console.log)
// Output:
// Apply a discount to: 100
// 95

@since2.0.0

tap
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const log: (...message: ReadonlyArray<any>) => Effect.Effect<void, never, never>

Logs one or more messages or error causes at the current log level, which is INFO by default. This function allows logging multiple items at once and can include detailed error information using Cause instances.

To adjust the log level, use the Logger.withMinimumLogLevel function.

@example

import { Cause, Effect } from "effect"
const program = Effect.log(
"message1",
"message2",
Cause.die("Oh no!"),
Cause.die("Oh uh!")
)
// Effect.runFork(program)
// Output:
// timestamp=... level=INFO fiber=#0 message=message1 message=message2 cause="Error: Oh no!
// Error: Oh uh!"

@since2.0.0

log
)
),
onSuccess: (a: number) => Effect.Effect<string, never, never>
onSuccess
: (
value: number
value
) =>
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
(`success: ${
value: number
value
}`).
Pipeable.pipe<Effect.Effect<string, never, never>, Effect.Effect<string, never, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<string, never, never>) => Effect.Effect<string, never, never>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const tap: <string, Effect.Effect<void, never, never>>(f: (a: string) => Effect.Effect<void, never, never>) => <E, R>(self: Effect.Effect<string, E, R>) => Effect.Effect<...> (+7 overloads)

Runs a side effect with the result of an effect without changing the original value.

When to Use

Use tap when you want to perform a side effect, like logging or tracking, without modifying the main value. This is useful when you need to observe or record an action but want the original value to be passed to the next step.

Details

tap works similarly to flatMap, but it ignores the result of the function passed to it. The value from the previous effect remains available for the next part of the chain. Note that if the side effect fails, the entire chain will fail too.

@example

// Title: Logging a step in a pipeline
import { Console, Effect, pipe } from "effect"
// Function to apply a discount safely to a transaction amount
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)
// Simulated asynchronous task to fetch a transaction amount from database
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const finalAmount = pipe(
fetchTransactionAmount,
// Log the fetched transaction amount
Effect.tap((amount) => Console.log(`Apply a discount to: ${amount}`)),
// `amount` is still available!
Effect.flatMap((amount) => applyDiscount(amount, 5))
)
Effect.runPromise(finalAmount).then(console.log)
// Output:
// Apply a discount to: 100
// 95

@since2.0.0

tap
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const log: (...message: ReadonlyArray<any>) => Effect.Effect<void, never, never>

Logs one or more messages or error causes at the current log level, which is INFO by default. This function allows logging multiple items at once and can include detailed error information using Cause instances.

To adjust the log level, use the Logger.withMinimumLogLevel function.

@example

import { Cause, Effect } from "effect"
const program = Effect.log(
"message1",
"message2",
Cause.die("Oh no!"),
Cause.die("Oh uh!")
)
// Effect.runFork(program)
// Output:
// timestamp=... level=INFO fiber=#0 message=message1 message=message2 cause="Error: Oh no!
// Error: Oh uh!"

@since2.0.0

log
))
})
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
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runSync: <string, never>(effect: Effect.Effect<string, never, never>) => string

Executes an effect synchronously, running it immediately and returning the result.

When to Use

Use runSync to run an effect that does not fail and does not include any asynchronous operations.

If the effect fails or involves asynchronous work, it will throw an error, and execution will stop where the failure or async operation occurs.

@seerunSyncExit for a version that returns an Exit type instead of throwing an error.

@example

// Title: Synchronous Logging
import { Effect } from "effect"
const program = Effect.sync(() => {
console.log("Hello, World!")
return 1
})
const result = Effect.runSync(program)
// Output: Hello, World!
console.log(result)
// Output: 1

@example

// Title: Incorrect Usage with Failing or Async Effects import { Effect } from "effect"

try { // Attempt to run an effect that fails Effect.runSync(Effect.fail("my error")) } catch (e) { console.error(e) } // Output: // (FiberFailure) Error: my error

try { // Attempt to run an effect that involves async work Effect.runSync(Effect.promise(() => Promise.resolve(1))) } catch (e) { console.error(e) } // Output: // (FiberFailure) AsyncFiberException: Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work

@since2.0.0

runSync
(
const program1: Effect.Effect<string, never, never>
program1
))
/*
Output:
timestamp=... level=INFO fiber=#0 message="success: 42"
success: 42
*/
const
const program2: Effect.Effect<string, never, never>
program2
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const matchEffect: <number, Error, never, string, never, never, string, never, never>(self: Effect.Effect<number, Error, never>, options: {
readonly onFailure: (e: Error) => Effect.Effect<string, never, never>;
readonly onSuccess: (a: number) => Effect.Effect<...>;
}) => Effect.Effect<...> (+1 overload)

Handles both success and failure cases of an effect, allowing for additional side effects.

Details

The matchEffect function is similar to

match

, but it enables you to perform side effects in the handlers for both success and failure outcomes.

When to Use

This is useful when you need to execute additional actions, like logging or notifying users, based on whether an effect succeeds or fails.

@seematch if you don't need side effects and only want to handle the result or failure.

@example

// Title: Handling Both Success and Failure Cases with Side Effects
import { Effect } from "effect"
const success: Effect.Effect<number, Error> = Effect.succeed(42)
const failure: Effect.Effect<number, Error> = Effect.fail(
new Error("Uh oh!")
)
const program1 = Effect.matchEffect(success, {
onFailure: (error) =>
Effect.succeed(`failure: ${error.message}`).pipe(
Effect.tap(Effect.log)
),
onSuccess: (value) =>
Effect.succeed(`success: ${value}`).pipe(Effect.tap(Effect.log))
})
console.log(Effect.runSync(program1))
// Output:
// timestamp=... level=INFO fiber=#0 message="success: 42"
// success: 42
const program2 = Effect.matchEffect(failure, {
onFailure: (error) =>
Effect.succeed(`failure: ${error.message}`).pipe(
Effect.tap(Effect.log)
),
onSuccess: (value) =>
Effect.succeed(`success: ${value}`).pipe(Effect.tap(Effect.log))
})
console.log(Effect.runSync(program2))
// Output:
// timestamp=... level=INFO fiber=#1 message="failure: Uh oh!"
// failure: Uh oh!

@since2.0.0

matchEffect
(
const failure: Effect.Effect<number, Error, never>
failure
, {
onFailure: (e: Error) => Effect.Effect<string, never, never>
onFailure
: (
error: Error
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
(`failure: ${
error: Error
error
.
Error.message: string
message
}`).
Pipeable.pipe<Effect.Effect<string, never, never>, Effect.Effect<string, never, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<string, never, never>) => Effect.Effect<string, never, never>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const tap: <string, Effect.Effect<void, never, never>>(f: (a: string) => Effect.Effect<void, never, never>) => <E, R>(self: Effect.Effect<string, E, R>) => Effect.Effect<...> (+7 overloads)

Runs a side effect with the result of an effect without changing the original value.

When to Use

Use tap when you want to perform a side effect, like logging or tracking, without modifying the main value. This is useful when you need to observe or record an action but want the original value to be passed to the next step.

Details

tap works similarly to flatMap, but it ignores the result of the function passed to it. The value from the previous effect remains available for the next part of the chain. Note that if the side effect fails, the entire chain will fail too.

@example

// Title: Logging a step in a pipeline
import { Console, Effect, pipe } from "effect"
// Function to apply a discount safely to a transaction amount
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)
// Simulated asynchronous task to fetch a transaction amount from database
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const finalAmount = pipe(
fetchTransactionAmount,
// Log the fetched transaction amount
Effect.tap((amount) => Console.log(`Apply a discount to: ${amount}`)),
// `amount` is still available!
Effect.flatMap((amount) => applyDiscount(amount, 5))
)
Effect.runPromise(finalAmount).then(console.log)
// Output:
// Apply a discount to: 100
// 95

@since2.0.0

tap
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const log: (...message: ReadonlyArray<any>) => Effect.Effect<void, never, never>

Logs one or more messages or error causes at the current log level, which is INFO by default. This function allows logging multiple items at once and can include detailed error information using Cause instances.

To adjust the log level, use the Logger.withMinimumLogLevel function.

@example

import { Cause, Effect } from "effect"
const program = Effect.log(
"message1",
"message2",
Cause.die("Oh no!"),
Cause.die("Oh uh!")
)
// Effect.runFork(program)
// Output:
// timestamp=... level=INFO fiber=#0 message=message1 message=message2 cause="Error: Oh no!
// Error: Oh uh!"

@since2.0.0

log
)
),
onSuccess: (a: number) => Effect.Effect<string, never, never>
onSuccess
: (
value: number
value
) =>
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
(`success: ${
value: number
value
}`).
Pipeable.pipe<Effect.Effect<string, never, never>, Effect.Effect<string, never, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<string, never, never>) => Effect.Effect<string, never, never>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const tap: <string, Effect.Effect<void, never, never>>(f: (a: string) => Effect.Effect<void, never, never>) => <E, R>(self: Effect.Effect<string, E, R>) => Effect.Effect<...> (+7 overloads)

Runs a side effect with the result of an effect without changing the original value.

When to Use

Use tap when you want to perform a side effect, like logging or tracking, without modifying the main value. This is useful when you need to observe or record an action but want the original value to be passed to the next step.

Details

tap works similarly to flatMap, but it ignores the result of the function passed to it. The value from the previous effect remains available for the next part of the chain. Note that if the side effect fails, the entire chain will fail too.

@example

// Title: Logging a step in a pipeline
import { Console, Effect, pipe } from "effect"
// Function to apply a discount safely to a transaction amount
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)
// Simulated asynchronous task to fetch a transaction amount from database
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const finalAmount = pipe(
fetchTransactionAmount,
// Log the fetched transaction amount
Effect.tap((amount) => Console.log(`Apply a discount to: ${amount}`)),
// `amount` is still available!
Effect.flatMap((amount) => applyDiscount(amount, 5))
)
Effect.runPromise(finalAmount).then(console.log)
// Output:
// Apply a discount to: 100
// 95

@since2.0.0

tap
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const log: (...message: ReadonlyArray<any>) => Effect.Effect<void, never, never>

Logs one or more messages or error causes at the current log level, which is INFO by default. This function allows logging multiple items at once and can include detailed error information using Cause instances.

To adjust the log level, use the Logger.withMinimumLogLevel function.

@example

import { Cause, Effect } from "effect"
const program = Effect.log(
"message1",
"message2",
Cause.die("Oh no!"),
Cause.die("Oh uh!")
)
// Effect.runFork(program)
// Output:
// timestamp=... level=INFO fiber=#0 message=message1 message=message2 cause="Error: Oh no!
// Error: Oh uh!"

@since2.0.0

log
))
})
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
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runSync: <string, never>(effect: Effect.Effect<string, never, never>) => string

Executes an effect synchronously, running it immediately and returning the result.

When to Use

Use runSync to run an effect that does not fail and does not include any asynchronous operations.

If the effect fails or involves asynchronous work, it will throw an error, and execution will stop where the failure or async operation occurs.

@seerunSyncExit for a version that returns an Exit type instead of throwing an error.

@example

// Title: Synchronous Logging
import { Effect } from "effect"
const program = Effect.sync(() => {
console.log("Hello, World!")
return 1
})
const result = Effect.runSync(program)
// Output: Hello, World!
console.log(result)
// Output: 1

@example

// Title: Incorrect Usage with Failing or Async Effects import { Effect } from "effect"

try { // Attempt to run an effect that fails Effect.runSync(Effect.fail("my error")) } catch (e) { console.error(e) } // Output: // (FiberFailure) Error: my error

try { // Attempt to run an effect that involves async work Effect.runSync(Effect.promise(() => Promise.resolve(1))) } catch (e) { console.error(e) } // Output: // (FiberFailure) AsyncFiberException: Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work

@since2.0.0

runSync
(
const program2: Effect.Effect<string, never, never>
program2
))
/*
Output:
timestamp=... level=INFO fiber=#1 message="failure: Uh oh!"
failure: Uh oh!
*/

The Effect.matchCause function allows you to handle failures with access to the full cause of the failure within a fiber.

This is useful for differentiating between different types of errors, such as regular failures, defects, or interruptions. You can provide specific handling logic for each failure type based on the cause.

Example (Handling Different Failure Causes)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
} from "effect"
const
const task: Effect.Effect<number, Error, never>
task
:
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
interface Effect<out A, out E = never, out R = never>

The Effect interface defines a value that describes a workflow or job, which can succeed or fail.

Details

The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management.

To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.

@since2.0.0

@since2.0.0

Effect
<number,
interface Error
Error
> =
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.

Details

This 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.

When to Use

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

@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
("Uh oh!")
const
const program: Effect.Effect<string, never, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const matchCause: <number, Error, never, string, string>(self: Effect.Effect<number, Error, never>, options: {
readonly onFailure: (cause: Cause<Error>) => string;
readonly onSuccess: (a: number) => string;
}) => Effect.Effect<...> (+1 overload)

Handles failures by matching the cause of failure.

Details

The matchCause function allows you to handle failures with access to the full cause of the failure within a fiber.

When to Use

This is useful for differentiating between different types of errors, such as regular failures, defects, or interruptions. You can provide specific handling logic for each failure type based on the cause.

@seematchCauseEffect if you need to perform side effects in the handlers.

@seematch if you don't need to handle the cause of the failure.

@example

// Title: Handling Different Failure Causes
import { Effect } from "effect"
const task: Effect.Effect<number, Error> = Effect.die("Uh oh!")
const program = Effect.matchCause(task, {
onFailure: (cause) => {
switch (cause._tag) {
case "Fail":
// Handle standard failure
return `Fail: ${cause.error.message}`
case "Die":
// Handle defects (unexpected errors)
return `Die: ${cause.defect}`
case "Interrupt":
// Handle interruption
return `${cause.fiberId} interrupted!`
}
// Fallback for other causes
return "failed due to other causes"
},
onSuccess: (value) =>
// task completes successfully
`succeeded with ${value} value`
})
Effect.runPromise(program).then(console.log)
// Output: "Die: Uh oh!"

@since2.0.0

matchCause
(
const task: Effect.Effect<number, Error, never>
task
, {
onFailure: (cause: Cause<Error>) => string
onFailure
: (
cause: Cause<Error>
cause
) => {
switch (
cause: Cause<Error>
cause
.
_tag: "Empty" | "Die" | "Interrupt" | "Fail" | "Sequential" | "Parallel"
_tag
) {
case "Fail":
// Handle standard failure
return `Fail: ${
cause: Fail<Error>
cause
.
Fail<Error>.error: Error
error
.
Error.message: string
message
}`
case "Die":
// Handle defects (unexpected errors)
return `Die: ${
cause: Die
cause
.
Die.defect: unknown
defect
}`
case "Interrupt":
// Handle interruption
return `${
cause: Interrupt
cause
.
Interrupt.fiberId: FiberId
fiberId
} interrupted!`
}
// Fallback for other causes
return "failed due to other causes"
},
onSuccess: (a: number) => string
onSuccess
: (
value: number
value
) =>
// task completes successfully
`succeeded with ${
value: number
value
} value`
})
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 program: Effect.Effect<string, never, never>
program
).
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: "Die: Uh oh!"

The Effect.matchCauseEffect function works similarly to Effect.matchCause, but it also allows you to perform additional side effects based on the failure cause.

This function provides access to the complete cause of the failure, making it possible to differentiate between various failure types, and allows you to respond accordingly while performing side effects (like logging or other operations).

Example (Handling Different Failure Causes with Side Effects)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Console
Console
} from "effect"
const
const task: Effect.Effect<number, Error, never>
task
:
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
interface Effect<out A, out E = never, out R = never>

The Effect interface defines a value that describes a workflow or job, which can succeed or fail.

Details

The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management.

To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.

@since2.0.0

@since2.0.0

Effect
<number,
interface Error
Error
> =
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.

Details

This 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.

When to Use

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

@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
("Uh oh!")
const
const program: Effect.Effect<void, never, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const matchCauseEffect: <number, Error, never, void, never, never, void, never, never>(self: Effect.Effect<number, Error, never>, options: {
readonly onFailure: (cause: Cause<Error>) => Effect.Effect<void, never, never>;
readonly onSuccess: (a: number) => Effect.Effect<...>;
}) => Effect.Effect<...> (+1 overload)

Handles failures with access to the cause and allows performing side effects.

Details

The matchCauseEffect function works similarly to

matchCause

, but it also allows you to perform additional side effects based on the failure cause. This function provides access to the complete cause of the failure, making it possible to differentiate between various failure types, and allows you to respond accordingly while performing side effects (like logging or other operations).

@seematchCause if you don't need side effects and only want to handle the result or failure.

@seematchEffect if you don't need to handle the cause of the failure.

@example

// Title: Handling Different Failure Causes with Side Effects
import { Effect, Console } from "effect"
const task: Effect.Effect<number, Error> = Effect.die("Uh oh!")
const program = Effect.matchCauseEffect(task, {
onFailure: (cause) => {
switch (cause._tag) {
case "Fail":
// Handle standard failure with a logged message
return Console.log(`Fail: ${cause.error.message}`)
case "Die":
// Handle defects (unexpected errors) by logging the defect
return Console.log(`Die: ${cause.defect}`)
case "Interrupt":
// Handle interruption and log the fiberId that was interrupted
return Console.log(`${cause.fiberId} interrupted!`)
}
// Fallback for other causes
return Console.log("failed due to other causes")
},
onSuccess: (value) =>
// Log success if the task completes successfully
Console.log(`succeeded with ${value} value`)
})
Effect.runPromise(program)
// Output: "Die: Uh oh!"

@since2.0.0

matchCauseEffect
(
const task: Effect.Effect<number, Error, never>
task
, {
onFailure: (cause: Cause<Error>) => Effect.Effect<void, never, never>
onFailure
: (
cause: Cause<Error>
cause
) => {
switch (
cause: Cause<Error>
cause
.
_tag: "Empty" | "Die" | "Interrupt" | "Fail" | "Sequential" | "Parallel"
_tag
) {
case "Fail":
// Handle standard failure with a logged message
return
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
(`Fail: ${
cause: Fail<Error>
cause
.
Fail<Error>.error: Error
error
.
Error.message: string
message
}`)
case "Die":
// Handle defects (unexpected errors) by logging the defect
return
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
(`Die: ${
cause: Die
cause
.
Die.defect: unknown
defect
}`)
case "Interrupt":
// Handle interruption and log the fiberId that was interrupted
return
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
(`${
cause: Interrupt
cause
.
Interrupt.fiberId: FiberId
fiberId
} interrupted!`)
}
// Fallback for other causes
return
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
("failed due to other causes")
},
onSuccess: (a: number) => Effect.Effect<void, never, never>
onSuccess
: (
value: number
value
) =>
// Log success if the task completes successfully
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
(`succeeded with ${
value: number
value
} value`)
})
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runPromise: <void, never>(effect: Effect.Effect<void, never, never>, options?: {
readonly signal?: AbortSignal;
} | undefined) => Promise<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<void, never, never>
program
)
// Output: "Die: Uh oh!"