Expected Errors
Expected errors are tracked at the type level by the Effect data type in the “Error channel”:
┌─── Represents the success type │ ┌─── Represents the error type │ │ ┌─── Represents required dependencies ▼ ▼ ▼Effect<Success, Error, Requirements>
This means that the Effect
type captures not only what the program returns on success but also what type of error it might produce.
Example (Creating an Effect That Can Fail)
In this example, we define a program that might randomly fail with an HttpError
.
1import { import Effect
Effect, import Random
Random } from "effect"2
3class class HttpError
HttpError {4 readonly (property) HttpError._tag: "HttpError"
_tag = "HttpError"5}6
7// ┌─── Effect<string, HttpError, never>8// ▼9const const program: Effect.Effect<string, HttpError, never>
program = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {10 // Generate a random number between 0 and 111 const const n: number
n = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next12
13 // Simulate an HTTP error14 if (const n: number
n < 0.5) {15 yield* import Effect
Effect.const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor HttpError(): HttpError
HttpError())16 }17
18 return "some result"19})
The type of program
tells us that it can either return a string
or fail with an HttpError
:
const program: Effect<string, HttpError, never>
In this case, we use a class to represent the HttpError
type, which allows us to define both the error type and a constructor. However, you can use whatever
you like to model your error types.
It’s also worth noting that we added a readonly _tag
field to the class:
class HttpError { // This field serves as a discriminant for the error readonly _tag = "HttpError"}
This discriminant field will be useful when we discuss APIs like Effect.catchTag, which help in handling specific error types.
In Effect, if a program can fail with multiple types of errors, they are automatically tracked as a union of those error types. This allows you to know exactly what errors can occur during execution, making error handling more precise and predictable.
The example below illustrates how errors are automatically tracked for you.
Example (Automatically Tracking Errors)
1import { import Effect
Effect, import Random
Random } from "effect"2
3class class HttpError
HttpError {4 readonly (property) HttpError._tag: "HttpError"
_tag = "HttpError"5}6
7class class ValidationError
ValidationError {8 readonly (property) ValidationError._tag: "ValidationError"
_tag = "ValidationError"9}10
11// ┌─── Effect<string, HttpError | ValidationError, never>12// ▼13const const program: Effect.Effect<string, HttpError | ValidationError, never>
program = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {14 // Generate two random numbers between 0 and 115 const const n1: number
n1 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next16 const const n2: number
n2 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next17
18 // Simulate an HTTP error19 if (const n1: number
n1 < 0.5) {20 yield* import Effect
Effect.const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor HttpError(): HttpError
HttpError())21 }22 // Simulate a validation error23 if (const n2: number
n2 < 0.5) {24 yield* import Effect
Effect.const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor ValidationError(): ValidationError
ValidationError())25 }26
27 return "some result"28})
Effect automatically keeps track of the possible errors that can occur during the execution of the program as a union:
const program: Effect<string, HttpError | ValidationError, never>
indicating that it can potentially fail with either a HttpError
or a ValidationError
.
When working with APIs like Effect.gen, Effect.map, Effect.flatMap, and Effect.andThen, it’s important to understand how they handle errors. These APIs are designed to short-circuit the execution upon encountering the first error.
What does this mean for you as a developer? Well, let’s say you have a chain of operations or a collection of effects to be executed in sequence. If any error occurs during the execution of one of these effects, the remaining computations will be skipped, and the error will be propagated to the final result.
In simpler terms, the short-circuiting behavior ensures that if something goes wrong at any step of your program, it won’t waste time executing unnecessary computations. Instead, it will immediately stop and return the error to let you know that something went wrong.
Example (Short-Circuiting Behavior)
1import { import Effect
Effect, import Console
Console } from "effect"2
3// Define three effects representing different tasks.4const const task1: Effect.Effect<void, never, never>
task1 = import Console
Console.const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>
log("Executing task1...")5const const task2: Effect.Effect<never, string, never>
task2 = import Effect
Effect.const fail: <string>(error: string) => Effect.Effect<never, string, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail("Something went wrong!")6const const task3: Effect.Effect<void, never, never>
task3 = import Console
Console.const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>
log("Executing task3...")7
8// Compose the three tasks to run them in sequence.9// If one of the tasks fails, the subsequent tasks won't be executed.10const const program: Effect.Effect<void, string, never>
program = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<void, never, never>> | YieldWrap<Effect.Effect<never, string, never>>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {11 yield* const task1: Effect.Effect<void, never, never>
task112 // After task1, task2 is executed, but it fails with an error13 yield* const task2: Effect.Effect<never, string, never>
task214 // This computation won't be executed because the previous one fails15 yield* const task3: Effect.Effect<void, never, never>
task316})17
18import Effect
Effect.const runPromiseExit: <void, string>(effect: Effect.Effect<void, string, never>, options?: {
readonly signal?: AbortSignal;
} | undefined) => Promise<Exit<void, string>>
Executes an effect and returns a `Promise` that resolves with an `Exit` describing the result.
Use `runPromiseExit` when you need detailed information about the outcome of the effect, including success or failure,
and you want to work with Promises.
runPromiseExit(const program: Effect.Effect<void, string, never>
program).(method) Promise<Exit<void, string>>.then<void, never>(onfulfilled?: ((value: Exit<void, string>) => void | PromiseLike<void>) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<...>
Attaches callbacks for the resolution and/or rejection of the Promise.
then(namespace console
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`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and
[`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). 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`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for
more information.
Example using the global `console`:
```js
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:
```js
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
```
console.(method) 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)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)).
```js
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()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.
log)19/*20Output:21Executing task1...22{23 _id: 'Exit',24 _tag: 'Failure',25 cause: { _id: 'Cause', _tag: 'Fail', failure: 'Something went wrong!' }26}27*/
This code snippet demonstrates the short-circuiting behavior when an error occurs.
Each operation depends on the successful execution of the previous one.
If any error occurs, the execution is short-circuited, and the error is propagated.
In this specific example, task3
is never executed because an error occurs in task2
.
The Effect.either
function transforms an Effect<A, E, R>
into an effect that encapsulates both potential failure and success within an Either data type:
Effect<A, E, R> -> Effect<Either<A, E>, never, R>
This means if you have an effect with the following type:
Effect<string, HttpError, never>
and you call Effect.either
on it, the type becomes:
Effect<Either<string, HttpError>, never, never>
The resulting effect cannot fail because the potential failure is now represented within the Either
’s Left
type.
The error type of the returned Effect
is specified as never
, confirming that the effect is structured to not fail.
By yielding an Either
, we gain the ability to “pattern match” on this type to handle both failure and success cases within the generator function.
Example (Using Effect.either
to Handle Errors)
1import { import Effect
Effect, import Either
Either, import Random
Random } from "effect"2
3class class HttpError
HttpError {4 readonly (property) HttpError._tag: "HttpError"
_tag = "HttpError"5}6
7class class ValidationError
ValidationError {8 readonly (property) ValidationError._tag: "ValidationError"
_tag = "ValidationError"9}10
11// ┌─── Effect<string, HttpError | ValidationError, never>12// ▼13const const program: Effect.Effect<string, HttpError | ValidationError, never>
program = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {14 const const n1: number
n1 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next15 const const n2: number
n2 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next16 if (const n1: number
n1 < 0.5) {17 yield* import Effect
Effect.const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor HttpError(): HttpError
HttpError())18 }19 if (const n2: number
n2 < 0.5) {20 yield* import Effect
Effect.const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor ValidationError(): ValidationError
ValidationError())21 }22 return "some result"23})24
25// ┌─── Effect<string, never, never>26// ▼27const const recovered: Effect.Effect<string, never, never>
recovered = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<Either.Either<string, HttpError | ValidationError>, never, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {28 // ┌─── Either<string, HttpError | ValidationError>29 // ▼30 const const failureOrSuccess: Either.Either<string, HttpError | ValidationError>
failureOrSuccess = yield* import Effect
Effect.const either: <string, HttpError | ValidationError, never>(self: Effect.Effect<string, HttpError | ValidationError, never>) => Effect.Effect<...>
Returns an effect whose failure and success have been lifted into an
`Either`. The resulting effect cannot fail, because the failure case has
been exposed as part of the `Either` success case.
This method is useful for recovering from effects that may fail.
The error parameter of the returned `Effect` is `never`, since it is
guaranteed the effect does not model failure.
either(const program: Effect.Effect<string, HttpError | ValidationError, never>
program)31 if (import Either
Either.const isLeft: <string, HttpError | ValidationError>(self: Either.Either<string, HttpError | ValidationError>) => self is Either.Left<HttpError | ValidationError, string>
Determine if a `Either` is a `Left`.
isLeft(const failureOrSuccess: Either.Either<string, HttpError | ValidationError>
failureOrSuccess)) {32 // Failure case: you can extract the error from the `left` property33 const const error: HttpError | ValidationError
error = const failureOrSuccess: Either.Left<HttpError | ValidationError, string>
failureOrSuccess.(property) Left<HttpError | ValidationError, string>.left: HttpError | ValidationError
left34 return `Recovering from ${const error: HttpError | ValidationError
error.(property) _tag: "HttpError" | "ValidationError"
_tag}`35 } else {36 // Success case: you can extract the value from the `right` property37 return const failureOrSuccess: Either.Right<HttpError | ValidationError, string>
failureOrSuccess.(property) Right<HttpError | ValidationError, string>.right: string
right38 }39})
As you can see since all errors are handled, the error type of the resulting effect recovered
is never
:
const recovered: Effect<string, never, never>
We can make the code less verbose by using the Either.match
function, which directly accepts the two callback functions for handling errors and successful values:
Example (Simplifying with Either.match
)
1import { import Effect
Effect, import Either
Either, import Random
Random } from "effect"2
21 collapsed lines
3class class HttpError
HttpError {4 readonly (property) HttpError._tag: "HttpError"
_tag = "HttpError"5}6
7class class ValidationError
ValidationError {8 readonly (property) ValidationError._tag: "ValidationError"
_tag = "ValidationError"9}10
11// ┌─── Effect<string, HttpError | ValidationError, never>12// ▼13const const program: Effect.Effect<string, HttpError | ValidationError, never>
program = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {14 const const n1: number
n1 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next15 const const n2: number
n2 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next16 if (const n1: number
n1 < 0.5) {17 yield* import Effect
Effect.const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor HttpError(): HttpError
HttpError())18 }19 if (const n2: number
n2 < 0.5) {20 yield* import Effect
Effect.const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor ValidationError(): ValidationError
ValidationError())21 }22 return "some result"23})24
25// ┌─── Effect<string, never, never>26// ▼27const const recovered: Effect.Effect<string, never, never>
recovered = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<Either.Either<string, HttpError | ValidationError>, never, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {28 // ┌─── Either<string, HttpError | ValidationError>29 // ▼30 const const failureOrSuccess: Either.Either<string, HttpError | ValidationError>
failureOrSuccess = yield* import Effect
Effect.const either: <string, HttpError | ValidationError, never>(self: Effect.Effect<string, HttpError | ValidationError, never>) => Effect.Effect<...>
Returns an effect whose failure and success have been lifted into an
`Either`. The resulting effect cannot fail, because the failure case has
been exposed as part of the `Either` success case.
This method is useful for recovering from effects that may fail.
The error parameter of the returned `Effect` is `never`, since it is
guaranteed the effect does not model failure.
either(const program: Effect.Effect<string, HttpError | ValidationError, never>
program)31 return import Either
Either.const match: <string, HttpError | ValidationError, string, string>(self: Either.Either<string, HttpError | ValidationError>, options: {
...;
}) => string (+1 overload)
Takes two functions and an `Either` value, if the value is a `Left` the inner value is applied to the `onLeft function,
if the value is a `Right` the inner value is applied to the `onRight` function.
match(const failureOrSuccess: Either.Either<string, HttpError | ValidationError>
failureOrSuccess, {32 (property) onLeft: (left: HttpError | ValidationError) => string
onLeft: ((parameter) error: HttpError | ValidationError
error) => `Recovering from ${(parameter) error: HttpError | ValidationError
error.(property) _tag: "HttpError" | "ValidationError"
_tag}`,33 (property) onRight: (right: string) => string
onRight: ((parameter) value: string
value) => (parameter) value: string
value // Do nothing in case of success34 })35})
The Effect.catchAll
function allows you to catch any error that occurs in the program and provide a fallback.
Example (Catching All Errors with Effect.catchAll
)
1import { import Effect
Effect, import Random
Random } from "effect"2
3class class HttpError
HttpError {4 readonly (property) HttpError._tag: "HttpError"
_tag = "HttpError"5}6
7class class ValidationError
ValidationError {8 readonly (property) ValidationError._tag: "ValidationError"
_tag = "ValidationError"9}10
11// ┌─── Effect<string, HttpError | ValidationError, never>12// ▼13const const program: Effect.Effect<string, HttpError | ValidationError, never>
program = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {14 const const n1: number
n1 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next15 const const n2: number
n2 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next16 if (const n1: number
n1 < 0.5) {17 yield* import Effect
Effect.const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor HttpError(): HttpError
HttpError())18 }19 if (const n2: number
n2 < 0.5) {20 yield* import Effect
Effect.const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor ValidationError(): ValidationError
ValidationError())21 }22 return "some result"23})24
25// ┌─── Effect<string, never, never>26// ▼27const const recovered: Effect.Effect<string, never, never>
recovered = const program: Effect.Effect<string, HttpError | ValidationError, never>
program.(method) Pipeable.pipe<Effect.Effect<string, HttpError | ValidationError, never>, Effect.Effect<string, never, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<string, HttpError | ValidationError, never>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe(28 import Effect
Effect.const catchAll: <HttpError | ValidationError, string, never, never>(f: (e: HttpError | ValidationError) => Effect.Effect<string, never, never>) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)
Recovers from all recoverable errors.
**Note**: that `Effect.catchAll` will not recover from unrecoverable defects. To
recover from both recoverable and unrecoverable errors use
`Effect.catchAllCause`.
catchAll(((parameter) error: HttpError | ValidationError
error) =>29 import Effect
Effect.const succeed: <string>(value: string) => Effect.Effect<string, never, never>
Creates an `Effect` that succeeds with the provided value.
Use this function to represent a successful computation that yields a value of type `A`.
The effect does not fail and does not require any environmental context.
succeed(`Recovering from ${(parameter) error: HttpError | ValidationError
error.(property) _tag: "HttpError" | "ValidationError"
_tag}`)30 )31)
We can observe that the type in the error channel of our program has changed to never
:
const recovered: Effect<string, never, never>
indicating that all errors have been handled.
The Effect.either
function transforms an Effect<A, E, R>
into an effect that encapsulates both potential failure and success within an Either data type:
Effect<A, E, R> -> Effect<Either<A, E>, never, R>
This means if you have an effect with the following type:
Effect<string, HttpError, never>
and you call Effect.either
on it, the type becomes:
Effect<Either<string, HttpError>, never, never>
The resulting effect cannot fail because the potential failure is now represented within the Either
’s Left
type.
The error type of the returned Effect
is specified as never
, confirming that the effect is structured to not fail.
By yielding an Either
, we gain the ability to “pattern match” on this type to handle both failure and success cases within the generator function.
Example (Handling Specific Errors with Effect.either
)
1import { import Effect
Effect, import Random
Random, import Either
Either } from "effect"2
3class class HttpError
HttpError {4 readonly (property) HttpError._tag: "HttpError"
_tag = "HttpError"5}6
7class class ValidationError
ValidationError {8 readonly (property) ValidationError._tag: "ValidationError"
_tag = "ValidationError"9}10
11// ┌─── Effect<string, HttpError | ValidationError, never>12// ▼13const const program: Effect.Effect<string, HttpError | ValidationError, never>
program = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {14 const const n1: number
n1 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next15 const const n2: number
n2 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next16 if (const n1: number
n1 < 0.5) {17 yield* import Effect
Effect.const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor HttpError(): HttpError
HttpError())18 }19 if (const n2: number
n2 < 0.5) {20 yield* import Effect
Effect.const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor ValidationError(): ValidationError
ValidationError())21 }22 return "some result"23})24
25// ┌─── Effect<string, ValidationError, never>26// ▼27const const recovered: Effect.Effect<string, ValidationError, never>
recovered = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<never, ValidationError, never>> | YieldWrap<Effect.Effect<Either.Either<string, HttpError | ValidationError>, never, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {28 const const failureOrSuccess: Either.Either<string, HttpError | ValidationError>
failureOrSuccess = yield* import Effect
Effect.const either: <string, HttpError | ValidationError, never>(self: Effect.Effect<string, HttpError | ValidationError, never>) => Effect.Effect<...>
Returns an effect whose failure and success have been lifted into an
`Either`. The resulting effect cannot fail, because the failure case has
been exposed as part of the `Either` success case.
This method is useful for recovering from effects that may fail.
The error parameter of the returned `Effect` is `never`, since it is
guaranteed the effect does not model failure.
either(const program: Effect.Effect<string, HttpError | ValidationError, never>
program)29 if (import Either
Either.const isLeft: <string, HttpError | ValidationError>(self: Either.Either<string, HttpError | ValidationError>) => self is Either.Left<HttpError | ValidationError, string>
Determine if a `Either` is a `Left`.
isLeft(const failureOrSuccess: Either.Either<string, HttpError | ValidationError>
failureOrSuccess)) {30 const const error: HttpError | ValidationError
error = const failureOrSuccess: Either.Left<HttpError | ValidationError, string>
failureOrSuccess.(property) Left<HttpError | ValidationError, string>.left: HttpError | ValidationError
left31 // Only handle HttpError errors32 if (const error: HttpError | ValidationError
error.(property) _tag: "HttpError" | "ValidationError"
_tag === "HttpError") {33 return "Recovering from HttpError"34 } else {35 // Rethrow ValidationError36 return yield* import Effect
Effect.const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(const error: ValidationError
error)37 }38 } else {39 return const failureOrSuccess: Either.Right<HttpError | ValidationError, string>
failureOrSuccess.(property) Right<HttpError | ValidationError, string>.right: string
right40 }41})
We can observe that the type in the error channel of our program has changed to only show ValidationError
:
const recovered: Effect<string, ValidationError, never>
indicating that HttpError
has been handled.
If we also want to handle ValidationError
, we can easily add another case to our code:
1import { import Effect
Effect, import Random
Random, import Either
Either } from "effect"2
19 collapsed lines
3class class HttpError
HttpError {4 readonly (property) HttpError._tag: "HttpError"
_tag = "HttpError"5}6
7class class ValidationError
ValidationError {8 readonly (property) ValidationError._tag: "ValidationError"
_tag = "ValidationError"9}10
11const const program: Effect.Effect<string, HttpError | ValidationError, never>
program = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {12 const const n1: number
n1 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next13 const const n2: number
n2 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next14 if (const n1: number
n1 < 0.5) {15 yield* import Effect
Effect.const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor HttpError(): HttpError
HttpError())16 }17 if (const n2: number
n2 < 0.5) {18 yield* import Effect
Effect.const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor ValidationError(): ValidationError
ValidationError())19 }20 return "some result"21})22
23// ┌─── Effect<string, never, never>24// ▼25const const recovered: Effect.Effect<string, never, never>
recovered = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<Either.Either<string, HttpError | ValidationError>, never, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {26 const const failureOrSuccess: Either.Either<string, HttpError | ValidationError>
failureOrSuccess = yield* import Effect
Effect.const either: <string, HttpError | ValidationError, never>(self: Effect.Effect<string, HttpError | ValidationError, never>) => Effect.Effect<...>
Returns an effect whose failure and success have been lifted into an
`Either`. The resulting effect cannot fail, because the failure case has
been exposed as part of the `Either` success case.
This method is useful for recovering from effects that may fail.
The error parameter of the returned `Effect` is `never`, since it is
guaranteed the effect does not model failure.
either(const program: Effect.Effect<string, HttpError | ValidationError, never>
program)27 if (import Either
Either.const isLeft: <string, HttpError | ValidationError>(self: Either.Either<string, HttpError | ValidationError>) => self is Either.Left<HttpError | ValidationError, string>
Determine if a `Either` is a `Left`.
isLeft(const failureOrSuccess: Either.Either<string, HttpError | ValidationError>
failureOrSuccess)) {28 const const error: HttpError | ValidationError
error = const failureOrSuccess: Either.Left<HttpError | ValidationError, string>
failureOrSuccess.(property) Left<HttpError | ValidationError, string>.left: HttpError | ValidationError
left29 // Handle both HttpError and ValidationError30 if (const error: HttpError | ValidationError
error.(property) _tag: "HttpError" | "ValidationError"
_tag === "HttpError") {31 return "Recovering from HttpError"32 } else {33 return "Recovering from ValidationError"34 }35 } else {36 return const failureOrSuccess: Either.Right<HttpError | ValidationError, string>
failureOrSuccess.(property) Right<HttpError | ValidationError, string>.right: string
right37 }38})
We can observe that the type in the error channel has changed to never
:
const recovered: Effect<string, never, never>
indicating that all errors have been handled.
If we want to catch and recover from only some types of errors and effectfully attempt recovery, we can use the Effect.catchSome
function.
Example (Handling Specific Errors with Effect.catchSome
)
1import { import Effect
Effect, import Random
Random, import Option
Option } from "effect"2
3class class HttpError
HttpError {4 readonly (property) HttpError._tag: "HttpError"
_tag = "HttpError"5}6
7class class ValidationError
ValidationError {8 readonly (property) ValidationError._tag: "ValidationError"
_tag = "ValidationError"9}10
11// ┌─── Effect<string, HttpError | ValidationError, never>12// ▼13const const program: Effect.Effect<string, HttpError | ValidationError, never>
program = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {14 const const n1: number
n1 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next15 const const n2: number
n2 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next16 if (const n1: number
n1 < 0.5) {17 yield* import Effect
Effect.const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor HttpError(): HttpError
HttpError())18 }19 if (const n2: number
n2 < 0.5) {20 yield* import Effect
Effect.const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor ValidationError(): ValidationError
ValidationError())21 }22 return "some result"23})24
25// ┌─── Effect<string, HttpError | ValidationError, never>26// ▼27const const recovered: Effect.Effect<string, HttpError | ValidationError, never>
recovered = const program: Effect.Effect<string, HttpError | ValidationError, never>
program.(method) Pipeable.pipe<Effect.Effect<string, HttpError | ValidationError, never>, Effect.Effect<string, HttpError | ValidationError, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe(28 import Effect
Effect.const catchSome: <HttpError | ValidationError, string, never, never>(pf: (e: HttpError | ValidationError) => Option.Option<Effect.Effect<string, never, never>>) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)
Recovers from some or all of the error cases.
catchSome(((parameter) error: HttpError | ValidationError
error) => {29 // Only handle HttpError errors30 if ((parameter) error: HttpError | ValidationError
error.(property) _tag: "HttpError" | "ValidationError"
_tag === "HttpError") {31 return import Option
Option.const some: <Effect.Effect<string, never, never>>(value: Effect.Effect<string, never, never>) => Option.Option<Effect.Effect<string, never, never>>
Creates a new `Option` that wraps the given value.
some(import Effect
Effect.const succeed: <string>(value: string) => Effect.Effect<string, never, never>
Creates an `Effect` that succeeds with the provided value.
Use this function to represent a successful computation that yields a value of type `A`.
The effect does not fail and does not require any environmental context.
succeed("Recovering from HttpError"))32 } else {33 return import Option
Option.const none: <never>() => Option.Option<never>
Creates a new `Option` that represents the absence of a value.
none()34 }35 })36)
In the code above, Effect.catchSome
takes a function that examines the error and decides whether to attempt recovery or not. If the error matches a specific condition, recovery can be attempted by returning Option.some(effect)
. If no recovery is possible, you can simply return Option.none()
.
It’s important to note that while Effect.catchSome
lets you catch specific errors, it doesn’t alter the error type itself.
Therefore, the resulting effect will still have the same error type as the original effect:
const recovered: Effect<string, HttpError | ValidationError, never>
Similar to Effect.catchSome
, the function Effect.catchIf
allows you to recover from specific errors based on a predicate.
Example (Catching Specific Errors with a Predicate)
1import { import Effect
Effect, import Random
Random } from "effect"2
3class class HttpError
HttpError {4 readonly (property) HttpError._tag: "HttpError"
_tag = "HttpError"5}6
7class class ValidationError
ValidationError {8 readonly (property) ValidationError._tag: "ValidationError"
_tag = "ValidationError"9}10
11// ┌─── Effect<string, HttpError | ValidationError, never>12// ▼13const const program: Effect.Effect<string, HttpError | ValidationError, never>
program = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {14 const const n1: number
n1 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next15 const const n2: number
n2 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next16 if (const n1: number
n1 < 0.5) {17 yield* import Effect
Effect.const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor HttpError(): HttpError
HttpError())18 }19 if (const n2: number
n2 < 0.5) {20 yield* import Effect
Effect.const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor ValidationError(): ValidationError
ValidationError())21 }22 return "some result"23})24
25// ┌─── Effect<string, ValidationError, never>26// ▼27const const recovered: Effect.Effect<string, ValidationError, never>
recovered = const program: Effect.Effect<string, HttpError | ValidationError, never>
program.(method) Pipeable.pipe<Effect.Effect<string, HttpError | ValidationError, never>, Effect.Effect<string, ValidationError, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe(28 import Effect
Effect.const catchIf: <HttpError | ValidationError, HttpError, string, never, never>(refinement: Refinement<HttpError | ValidationError, HttpError>, f: (e: HttpError) => Effect.Effect<...>) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+3 overloads)
Recovers from errors that match the given predicate.
catchIf(29 // Only handle HttpError errors30 ((parameter) error: HttpError | ValidationError
error) => (parameter) error: HttpError | ValidationError
error.(property) _tag: "HttpError" | "ValidationError"
_tag === "HttpError",31 () => import Effect
Effect.const succeed: <string>(value: string) => Effect.Effect<string, never, never>
Creates an `Effect` that succeeds with the provided value.
Use this function to represent a successful computation that yields a value of type `A`.
The effect does not fail and does not require any environmental context.
succeed("Recovering from HttpError")32 )33)
It’s important to note that for TypeScript versions < 5.5, while Effect.catchIf
lets you catch specific errors, it doesn’t alter the error type itself.
Therefore, the resulting effect will still have the same error type as the original effect:
const recovered: Effect<string, HttpError | ValidationError, never>
In TypeScript versions >= 5.5, improved type narrowing causes the resulting error type to be inferred as ValidationError
.
If you provide a user-defined type guard instead of a predicate, the resulting error type will be pruned, returning an Effect<string, ValidationError, never>
:
1import { import Effect
Effect, import Random
Random } from "effect"2
21 collapsed lines
3class class HttpError
HttpError {4 readonly (property) HttpError._tag: "HttpError"
_tag = "HttpError"5}6
7class class ValidationError
ValidationError {8 readonly (property) ValidationError._tag: "ValidationError"
_tag = "ValidationError"9}10
11// ┌─── Effect<string, HttpError | ValidationError, never>12// ▼13const const program: Effect.Effect<string, HttpError | ValidationError, never>
program = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {14 const const n1: number
n1 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next15 const const n2: number
n2 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next16 if (const n1: number
n1 < 0.5) {17 yield* import Effect
Effect.const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor HttpError(): HttpError
HttpError())18 }19 if (const n2: number
n2 < 0.5) {20 yield* import Effect
Effect.const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor ValidationError(): ValidationError
ValidationError())21 }22 return "some result"23})24
25// ┌─── Effect<string, ValidationError, never>26// ▼27const const recovered: Effect.Effect<string, ValidationError, never>
recovered = const program: Effect.Effect<string, HttpError | ValidationError, never>
program.(method) Pipeable.pipe<Effect.Effect<string, HttpError | ValidationError, never>, Effect.Effect<string, ValidationError, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe(28 import Effect
Effect.const catchIf: <HttpError | ValidationError, HttpError, string, never, never>(refinement: Refinement<HttpError | ValidationError, HttpError>, f: (e: HttpError) => Effect.Effect<...>) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+3 overloads)
Recovers from errors that match the given predicate.
catchIf(29 // User-defined type guard30 ((parameter) error: HttpError | ValidationError
error): (parameter) error: HttpError | ValidationError
error is class HttpError
HttpError => (parameter) error: HttpError | ValidationError
error.(property) _tag: "HttpError" | "ValidationError"
_tag === "HttpError",31 () => import Effect
Effect.const succeed: <string>(value: string) => Effect.Effect<string, never, never>
Creates an `Effect` that succeeds with the provided value.
Use this function to represent a successful computation that yields a value of type `A`.
The effect does not fail and does not require any environmental context.
succeed("Recovering from HttpError")32 )33)
If your program’s errors are all tagged with a _tag
field that acts as a discriminator you can use the Effect.catchTag
function to catch and handle specific errors with precision.
Example (Handling Errors by Tag with Effect.catchTag
)
1import { import Effect
Effect, import Random
Random } from "effect"2
3class class HttpError
HttpError {4 readonly (property) HttpError._tag: "HttpError"
_tag = "HttpError"5}6
7class class ValidationError
ValidationError {8 readonly (property) ValidationError._tag: "ValidationError"
_tag = "ValidationError"9}10
11// ┌─── Effect<string, HttpError | ValidationError, never>12// ▼13const const program: Effect.Effect<string, HttpError | ValidationError, never>
program = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {14 const const n1: number
n1 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next15 const const n2: number
n2 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next16 if (const n1: number
n1 < 0.5) {17 yield* import Effect
Effect.const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor HttpError(): HttpError
HttpError())18 }19 if (const n2: number
n2 < 0.5) {20 yield* import Effect
Effect.const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor ValidationError(): ValidationError
ValidationError())21 }22 return "some result"23})24
25// ┌─── Effect<string, ValidationError, never>26// ▼27const const recovered: Effect.Effect<string, ValidationError, never>
recovered = const program: Effect.Effect<string, HttpError | ValidationError, never>
program.(method) Pipeable.pipe<Effect.Effect<string, HttpError | ValidationError, never>, Effect.Effect<string, ValidationError, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe(28 // Only handle HttpError errors29 import Effect
Effect.const catchTag: <"HttpError", HttpError | ValidationError, string, never, never>(k: "HttpError", f: (e: HttpError) => Effect.Effect<string, never, never>) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)
Recovers from the specified tagged error.
catchTag("HttpError", ((parameter) _HttpError: HttpError
_HttpError) =>30 import Effect
Effect.const succeed: <string>(value: string) => Effect.Effect<string, never, never>
Creates an `Effect` that succeeds with the provided value.
Use this function to represent a successful computation that yields a value of type `A`.
The effect does not fail and does not require any environmental context.
succeed("Recovering from HttpError")31 )32)
In the example above, the Effect.catchTag
function allows us to handle HttpError
specifically.
If a HttpError
occurs during the execution of the program, the provided error handler function will be invoked,
and the program will proceed with the recovery logic specified within the handler.
We can observe that the type in the error channel of our program has changed to only show ValidationError
:
const recovered: Effect<string, ValidationError, never>
indicating that HttpError
has been handled.
If we also wanted to handle ValidationError
, we can simply add another catchTag
:
Example (Handling Multiple Error Types with catchTag
)
1import { import Effect
Effect, import Random
Random } from "effect"2
21 collapsed lines
3class class HttpError
HttpError {4 readonly (property) HttpError._tag: "HttpError"
_tag = "HttpError"5}6
7class class ValidationError
ValidationError {8 readonly (property) ValidationError._tag: "ValidationError"
_tag = "ValidationError"9}10
11// ┌─── Effect<string, HttpError | ValidationError, never>12// ▼13const const program: Effect.Effect<string, HttpError | ValidationError, never>
program = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {14 const const n1: number
n1 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next15 const const n2: number
n2 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next16 if (const n1: number
n1 < 0.5) {17 yield* import Effect
Effect.const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor HttpError(): HttpError
HttpError())18 }19 if (const n2: number
n2 < 0.5) {20 yield* import Effect
Effect.const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor ValidationError(): ValidationError
ValidationError())21 }22 return "some result"23})24
25// ┌─── Effect<string, never, never>26// ▼27const const recovered: Effect.Effect<string, never, never>
recovered = const program: Effect.Effect<string, HttpError | ValidationError, never>
program.(method) Pipeable.pipe<Effect.Effect<string, HttpError | ValidationError, never>, Effect.Effect<string, ValidationError, never>, Effect.Effect<...>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>, bc: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe(28 // Handle both HttpError and ValidationError29 import Effect
Effect.const catchTag: <"HttpError", HttpError | ValidationError, string, never, never>(k: "HttpError", f: (e: HttpError) => Effect.Effect<string, never, never>) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)
Recovers from the specified tagged error.
catchTag("HttpError", ((parameter) _HttpError: HttpError
_HttpError) =>30 import Effect
Effect.const succeed: <string>(value: string) => Effect.Effect<string, never, never>
Creates an `Effect` that succeeds with the provided value.
Use this function to represent a successful computation that yields a value of type `A`.
The effect does not fail and does not require any environmental context.
succeed("Recovering from HttpError")31 ),32 import Effect
Effect.const catchTag: <"ValidationError", ValidationError, string, never, never>(k: "ValidationError", f: (e: ValidationError) => Effect.Effect<string, never, never>) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)
Recovers from the specified tagged error.
catchTag("ValidationError", ((parameter) _ValidationError: ValidationError
_ValidationError) =>33 import Effect
Effect.const succeed: <string>(value: string) => Effect.Effect<string, never, never>
Creates an `Effect` that succeeds with the provided value.
Use this function to represent a successful computation that yields a value of type `A`.
The effect does not fail and does not require any environmental context.
succeed("Recovering from ValidationError")34 )35)
We can observe that the type in the error channel of our program has changed to never
:
const recovered: Effect<string, never, never>
indicating that all errors have been handled.
Instead of using the Effect.catchTag
function multiple times to handle individual error types, we have a more convenient option called Effect.catchTags
. With Effect.catchTags
, we can handle multiple errors in a single block of code.
Example (Handling Multiple Error Types with catchTags
)
1import { import Effect
Effect, import Random
Random } from "effect"2
3class class HttpError
HttpError {4 readonly (property) HttpError._tag: "HttpError"
_tag = "HttpError"5}6
7class class ValidationError
ValidationError {8 readonly (property) ValidationError._tag: "ValidationError"
_tag = "ValidationError"9}10
11// ┌─── Effect<string, HttpError | ValidationError, never>12// ▼13const const program: Effect.Effect<string, HttpError | ValidationError, never>
program = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<number, never, never>> | YieldWrap<Effect.Effect<never, HttpError, never>> | YieldWrap<Effect.Effect<never, ValidationError, never>>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {14 const const n1: number
n1 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next15 const const n2: number
n2 = yield* import Random
Random.const next: Effect.Effect<number, never, never>
Returns the next numeric value from the pseudo-random number generator.
next16 if (const n1: number
n1 < 0.5) {17 yield* import Effect
Effect.const fail: <HttpError>(error: HttpError) => Effect.Effect<never, HttpError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor HttpError(): HttpError
HttpError())18 }19 if (const n2: number
n2 < 0.5) {20 yield* import Effect
Effect.const fail: <ValidationError>(error: ValidationError) => Effect.Effect<never, ValidationError, never>
Creates an `Effect` that represents a recoverable error.
This `Effect` does not succeed but instead fails with the provided error. The
failure can be of any type, and will propagate through the effect pipeline
unless handled.
Use this function when you want to explicitly signal an error in an `Effect`
computation. The failed effect can later be handled with functions like
{@link
catchAll
}
or
{@link
catchTag
}
.
fail(new constructor ValidationError(): ValidationError
ValidationError())21 }22 return "some result"23})24
25// ┌─── Effect<string, never, never>26// ▼27const const recovered: Effect.Effect<string, never, never>
recovered = const program: Effect.Effect<string, HttpError | ValidationError, never>
program.(method) Pipeable.pipe<Effect.Effect<string, HttpError | ValidationError, never>, Effect.Effect<string, never, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<string, HttpError | ValidationError, never>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe(28 import Effect
Effect.const catchTags: <HttpError | ValidationError, {
HttpError: (_HttpError: HttpError) => Effect.Effect<string, never, never>;
ValidationError: (_ValidationError: ValidationError) => Effect.Effect<...>;
}>(cases: {
...;
}) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)
Recovers from the specified tagged errors.
catchTags({29 (property) HttpError: (_HttpError: HttpError) => Effect.Effect<string, never, never>
HttpError: ((parameter) _HttpError: HttpError
_HttpError) =>30 import Effect
Effect.const succeed: <string>(value: string) => Effect.Effect<string, never, never>
Creates an `Effect` that succeeds with the provided value.
Use this function to represent a successful computation that yields a value of type `A`.
The effect does not fail and does not require any environmental context.
succeed(`Recovering from HttpError`),31 (property) ValidationError: (_ValidationError: ValidationError) => Effect.Effect<string, never, never>
ValidationError: ((parameter) _ValidationError: ValidationError
_ValidationError) =>32 import Effect
Effect.const succeed: <string>(value: string) => Effect.Effect<string, never, never>
Creates an `Effect` that succeeds with the provided value.
Use this function to represent a successful computation that yields a value of type `A`.
The effect does not fail and does not require any environmental context.
succeed(`Recovering from ValidationError`)33 })34)
This function takes an object where each property represents a specific error _tag
("HttpError"
and "ValidationError"
in this case),
and the corresponding value is the error handler function to be executed when that particular error occurs.