# Effect vs neverthrow
import { Tabs, TabItem } from "@astrojs/starlight/components"
When working with error handling in TypeScript, both [neverthrow](https://github.com/supermacro/neverthrow) and Effect provide useful abstractions for modeling
success and failure without exceptions. They share many concepts, such as wrapping computations in a safe container,
transforming values with `map`, handling errors with `mapErr`/`mapLeft`, and offering utilities to combine or unwrap results.
This page shows a side-by-side comparison of neverthrow and Effect APIs for common use cases.
If you're already familiar with neverthrow, the examples will help you understand how to achieve the same patterns with Effect.
If you're starting fresh, the comparison highlights the similarities and differences so you can decide which library better fits your project.
neverthrow exposes **instance methods** (for example, `result.map(...)`).
Effect exposes **functions** on `Either` (for example, `Either.map(result, ...)`) and supports a `pipe` style for readability and better tree shaking.
## Synchronous API
### ok
**Example** (Creating a success result)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { ok } from "neverthrow"
const result = ok({ myData: "test" })
result.isOk() // true
result.isErr() // false
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Either from "effect/Either"
const result = Either.right({ myData: "test" })
Either.isRight(result) // true
Either.isLeft(result) // false
```
</TabItem>
</Tabs>
### err
**Example** (Creating a failure result)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { err } from "neverthrow"
const result = err("Oh no")
result.isOk() // false
result.isErr() // true
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Either from "effect/Either"
const result = Either.left("Oh no")
Either.isRight(result) // false
Either.isLeft(result) // true
```
</TabItem>
</Tabs>
### map
**Example** (Transforming the success value)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { Result } from "neverthrow"
declare function getLines(s: string): Result<Array<string>, Error>
const result = getLines("1\n2\n3\n4\n")
// this Result now has a Array<number> inside it
const newResult = result.map((arr) => arr.map(parseInt))
newResult.isOk() // true
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Either from "effect/Either"
declare function getLines(s: string): Either.Either<Array<string>, Error>
const result = getLines("1\n2\n3\n4\n")
// this Either now has a Array<number> inside it
const newResult = result.pipe(Either.map((arr) => arr.map(parseInt)))
Either.isRight(newResult) // true
```
</TabItem>
</Tabs>
### mapErr
**Example** (Transforming the error value)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { Result } from "neverthrow"
declare function parseHeaders(
raw: string
): Result<Record<string, string>, string>
const rawHeaders = "nonsensical gibberish and badly formatted stuff"
const result = parseHeaders(rawHeaders)
// const newResult: Result<Record<string, string>, Error>
const newResult = result.mapErr((err) => new Error(err))
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Either from "effect/Either"
declare function parseHeaders(
raw: string
): Either.Either<Record<string, string>, string>
const rawHeaders = "nonsensical gibberish and badly formatted stuff"
const result = parseHeaders(rawHeaders)
// const newResult: Either<Record<string, string>, Error>
const newResult = result.pipe(Either.mapLeft((err) => new Error(err)))
```
</TabItem>
</Tabs>
### unwrapOr
**Example** (Providing a default value)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { err } from "neverthrow"
const result = err("Oh no")
const multiply = (value: number): number => value * 2
const unwrapped = result.map(multiply).unwrapOr(10)
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Either from "effect/Either"
const result = Either.left("Oh no")
const multiply = (value: number): number => value * 2
const unwrapped = result.pipe(
Either.map(multiply),
Either.getOrElse(() => 10)
)
```
</TabItem>
</Tabs>
### andThen
**Example** (Chaining computations that may fail)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { ok, Result, err } from "neverthrow"
const sqrt = (n: number): Result<number, string> =>
n > 0 ? ok(Math.sqrt(n)) : err("n must be positive")
ok(16).andThen(sqrt).andThen(sqrt)
// Ok(2)
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Either from "effect/Either"
const sqrt = (n: number): Either.Either<number, string> =>
n > 0 ? Either.right(Math.sqrt(n)) : Either.left("n must be positive")
Either.right(16).pipe(Either.andThen(sqrt), Either.andThen(sqrt))
// Right(2)
```
</TabItem>
</Tabs>
### asyncAndThen
**Example** (Chaining asynchronous computations that may fail)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { ok, okAsync } from "neverthrow"
// const result: ResultAsync<number, never>
const result = ok(1).asyncAndThen((n) => okAsync(n + 1))
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Either from "effect/Either"
import * as Effect from "effect/Effect"
// const result: Effect<number, never, never>
const result = Either.right(1).pipe(
Effect.andThen((n) => Effect.succeed(n + 1))
)
```
</TabItem>
</Tabs>
### orElse
**Example** (Providing an alternative on failure)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { Result, err, ok } from "neverthrow"
enum DatabaseError {
PoolExhausted = "PoolExhausted",
NotFound = "NotFound"
}
const dbQueryResult: Result<string, DatabaseError> = err(
DatabaseError.NotFound
)
const updatedQueryResult = dbQueryResult.orElse((dbError) =>
dbError === DatabaseError.NotFound
? ok("User does not exist")
: err(500)
)
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Either from "effect/Either"
enum DatabaseError {
PoolExhausted = "PoolExhausted",
NotFound = "NotFound"
}
const dbQueryResult: Either.Either<string, DatabaseError> = Either.left(
DatabaseError.NotFound
)
const updatedQueryResult = dbQueryResult.pipe(
Either.orElse((dbError) =>
dbError === DatabaseError.NotFound
? Either.right("User does not exist")
: Either.left(500)
)
)
```
</TabItem>
</Tabs>
### match
**Example** (Pattern matching on success or failure)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { Result } from "neverthrow"
declare const myResult: Result<number, string>
myResult.match(
(value) => `The value is ${value}`,
(error) => `The error is ${error}`
)
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Either from "effect/Either"
declare const myResult: Either.Either<number, string>
myResult.pipe(
Either.match({
onLeft: (error) => `The error is ${error}`,
onRight: (value) => `The value is ${value}`
})
)
```
</TabItem>
</Tabs>
### asyncMap
**Example** (Parsing headers and looking up a user)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { Result } from "neverthrow"
interface User {}
declare function parseHeaders(
raw: string
): Result<Record<string, string>, string>
declare function findUserInDatabase(
authorization: string
): Promise<User | undefined>
const rawHeader = "Authorization: Bearer 1234567890"
// const asyncResult: ResultAsync<User | undefined, string>
const asyncResult = parseHeaders(rawHeader)
.map((kvMap) => kvMap["Authorization"])
.asyncMap((authorization) =>
authorization === undefined
? Promise.resolve(undefined)
: findUserInDatabase(authorization)
)
```
</TabItem>
<TabItem label="Effect">
```ts twoslash "UnknownException"
import * as Either from "effect/Either"
import * as Effect from "effect/Effect"
interface User {}
declare function parseHeaders(
raw: string
): Either.Either<Record<string, string>, string>
declare function findUserInDatabase(
authorization: string
): Promise<User | undefined>
const rawHeader = "Authorization: Bearer 1234567890"
// const asyncResult: Effect<User | undefined, string | UnknownException>
const asyncResult = parseHeaders(rawHeader).pipe(
Either.map((kvMap) => kvMap["Authorization"]),
Effect.andThen((authorization) =>
authorization === undefined
? Promise.resolve(undefined)
: findUserInDatabase(authorization)
)
)
```
**Note**. In neverthrow, `asyncMap` works with Promises directly.
In Effect, passing a Promise to combinators like `Effect.andThen` automatically lifts it into an `Effect`.
If the Promise rejects, the rejection is turned into an `UnknownException`, which is why the error type is widened to `string | UnknownException`.
</TabItem>
</Tabs>
### combine
**Example** (Combining multiple results)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { Result, ok } from "neverthrow"
const results: Result<number, string>[] = [ok(1), ok(2)]
// const combined: Result<number[], string>
const combined = Result.combine(results)
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Either from "effect/Either"
const results: Either.Either<number, string>[] = [
Either.right(1),
Either.right(2)
]
// const combined: Either<number[], string>
const combined = Either.all(results)
```
</TabItem>
</Tabs>
### combineWithAllErrors
**Example** (Collecting all errors and successes)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { Result, ok, err } from "neverthrow"
const results: Result<number, string>[] = [
ok(123),
err("boooom!"),
ok(456),
err("ahhhhh!")
]
const result = Result.combineWithAllErrors(results)
// result is Err(['boooom!', 'ahhhhh!'])
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Either from "effect/Either"
import * as Array from "effect/Array"
const results: Either.Either<number, string>[] = [
Either.right(123),
Either.left("boooom!"),
Either.right(456),
Either.left("ahhhhh!")
]
const errors = Array.getLefts(results)
// errors is ['boooom!', 'ahhhhh!']
const successes = Array.getRights(results)
// successes is [123, 456]
```
</TabItem>
</Tabs>
**Note**. There is no exact equivalent of `Result.combineWithAllErrors` in Effect.
Use `Array.getLefts` to collect all errors and `Array.getRights` to collect all successes.
## Asynchronous API
In the examples below we use `Effect.runPromise` to run an effect and return a `Promise`.
You can also use other APIs such as `Effect.runPromiseExit`, which can capture additional cases like defects (runtime errors) and interruptions.
### okAsync
**Example** (Creating a successful async result)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { okAsync } from "neverthrow"
const myResultAsync = okAsync({ myData: "test" })
const result = await myResultAsync
result.isOk() // true
result.isErr() // false
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Either from "effect/Either"
import * as Effect from "effect/Effect"
const myResultAsync = Effect.succeed({ myData: "test" })
const result = await Effect.runPromise(Effect.either(myResultAsync))
Either.isRight(result) // true
Either.isLeft(result) // false
```
</TabItem>
</Tabs>
### errAsync
**Example** (Creating a failed async result)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { errAsync } from "neverthrow"
const myResultAsync = errAsync("Oh no")
const myResult = await myResultAsync
myResult.isOk() // false
myResult.isErr() // true
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Either from "effect/Either"
import * as Effect from "effect/Effect"
const myResultAsync = Effect.fail("Oh no")
const result = await Effect.runPromise(Effect.either(myResultAsync))
Either.isRight(result) // false
Either.isLeft(result) // true
```
</TabItem>
</Tabs>
### fromThrowable
**Example** (Wrapping a Promise-returning function that may throw)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { ResultAsync } from "neverthrow"
interface User {}
declare function insertIntoDb(user: User): Promise<User>
// (user: User) => ResultAsync<User, Error>
const insertUser = ResultAsync.fromThrowable(
insertIntoDb,
() => new Error("Database error")
)
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Effect from "effect/Effect"
interface User {}
declare function insertIntoDb(user: User): Promise<User>
// (user: User) => Effect<User, Error>
const insertUser = (user: User) =>
Effect.tryPromise({
try: () => insertIntoDb(user),
catch: () => new Error("Database error")
})
```
</TabItem>
</Tabs>
### map
**Example** (Transforming the success value)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { Result, ResultAsync } from "neverthrow"
interface User {
readonly name: string
}
declare function findUsersIn(
country: string
): ResultAsync<Array<User>, Error>
const usersInCanada = findUsersIn("Canada")
const namesInCanada = usersInCanada.map((users: Array<User>) =>
users.map((user) => user.name)
)
// We can extract the Result using .then() or await
namesInCanada.then((namesResult: Result<Array<string>, Error>) => {
if (namesResult.isErr()) {
console.log(
"Couldn't get the users from the database",
namesResult.error
)
} else {
console.log(
"Users in Canada are named: " + namesResult.value.join(",")
)
}
})
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Effect from "effect/Effect"
import * as Either from "effect/Either"
interface User {
readonly name: string
}
declare function findUsersIn(
country: string
): Effect.Effect<Array<User>, Error>
const usersInCanada = findUsersIn("Canada")
const namesInCanada = usersInCanada.pipe(
Effect.map((users: Array<User>) => users.map((user) => user.name))
)
// We can extract the Either using Effect.either
Effect.runPromise(Effect.either(namesInCanada)).then(
(namesResult: Either.Either<Array<string>, Error>) => {
if (Either.isLeft(namesResult)) {
console.log(
"Couldn't get the users from the database",
namesResult.left
)
} else {
console.log(
"Users in Canada are named: " + namesResult.right.join(",")
)
}
}
)
```
</TabItem>
</Tabs>
### mapErr
**Example** (Transforming the error value)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { Result, ResultAsync } from "neverthrow"
interface User {
readonly name: string
}
declare function findUsersIn(
country: string
): ResultAsync<Array<User>, Error>
const usersInCanada = findUsersIn("Canada").mapErr((error: Error) => {
// The only error we want to pass to the user is "Unknown country"
if (error.message === "Unknown country") {
return error.message
}
// All other errors will be labelled as a system error
return "System error, please contact an administrator."
})
usersInCanada.then((usersResult: Result<Array<User>, string>) => {
if (usersResult.isErr()) {
console.log(
"Couldn't get the users from the database",
usersResult.error
)
} else {
console.log("Users in Canada are: " + usersResult.value.join(","))
}
})
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Effect from "effect/Effect"
import * as Either from "effect/Either"
interface User {
readonly name: string
}
declare function findUsersIn(
country: string
): Effect.Effect<Array<User>, Error>
const usersInCanada = findUsersIn("Canada").pipe(
Effect.mapError((error: Error) => {
// The only error we want to pass to the user is "Unknown country"
if (error.message === "Unknown country") {
return error.message
}
// All other errors will be labelled as a system error
return "System error, please contact an administrator."
})
)
Effect.runPromise(Effect.either(usersInCanada)).then(
(usersResult: Either.Either<Array<User>, string>) => {
if (Either.isLeft(usersResult)) {
console.log(
"Couldn't get the users from the database",
usersResult.left
)
} else {
console.log("Users in Canada are: " + usersResult.right.join(","))
}
}
)
```
</TabItem>
</Tabs>
### unwrapOr
**Example** (Providing a default value when async fails)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { errAsync } from "neverthrow"
const unwrapped = await errAsync(0).unwrapOr(10)
// unwrapped = 10
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Effect from "effect/Effect"
const unwrapped = await Effect.runPromise(
Effect.fail(0).pipe(Effect.orElseSucceed(() => 10))
)
// unwrapped = 10
```
</TabItem>
</Tabs>
### andThen
**Example** (Chaining multiple async computations)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { Result, ResultAsync } from "neverthrow"
interface User {}
declare function validateUser(user: User): ResultAsync<User, Error>
declare function insertUser(user: User): ResultAsync<User, Error>
declare function sendNotification(user: User): ResultAsync<void, Error>
const user: User = {}
const resAsync = validateUser(user)
.andThen(insertUser)
.andThen(sendNotification)
resAsync.then((res: Result<void, Error>) => {
if (res.isErr()) {
console.log("Oops, at least one step failed", res.error)
} else {
console.log(
"User has been validated, inserted and notified successfully."
)
}
})
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Effect from "effect/Effect"
import * as Either from "effect/Either"
interface User {}
declare function validateUser(user: User): Effect.Effect<User, Error>
declare function insertUser(user: User): Effect.Effect<User, Error>
declare function sendNotification(user: User): Effect.Effect<void, Error>
const user: User = {}
const resAsync = validateUser(user).pipe(
Effect.andThen(insertUser),
Effect.andThen(sendNotification)
)
Effect.runPromise(Effect.either(resAsync)).then(
(res: Either.Either<void, Error>) => {
if (Either.isLeft(res)) {
console.log("Oops, at least one step failed", res.left)
} else {
console.log(
"User has been validated, inserted and notified successfully."
)
}
}
)
```
</TabItem>
</Tabs>
### orElse
**Example** (Fallback when an async operation fails)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { ResultAsync, ok } from "neverthrow"
interface User {}
declare function fetchUserData(id: string): ResultAsync<User, Error>
declare function getDefaultUser(): User
const userId = "123"
// Try to fetch user data, but provide a default if it fails
const userResult = fetchUserData(userId).orElse(() =>
ok(getDefaultUser())
)
userResult.then((result) => {
if (result.isOk()) {
console.log("User data:", result.value)
}
})
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Effect from "effect/Effect"
import * as Either from "effect/Either"
interface User {}
declare function fetchUserData(id: string): Effect.Effect<User, Error>
declare function getDefaultUser(): User
const userId = "123"
// Try to fetch user data, but provide a default if it fails
const userResult = fetchUserData(userId).pipe(
Effect.orElse(() => Effect.succeed(getDefaultUser()))
)
Effect.runPromise(Effect.either(userResult)).then((result) => {
if (Either.isRight(result)) {
console.log("User data:", result.right)
}
})
```
</TabItem>
</Tabs>
### match
**Example** (Handling success and failure at the end of a chain)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { ResultAsync } from "neverthrow"
interface User {
readonly name: string
}
declare function validateUser(user: User): ResultAsync<User, Error>
declare function insertUser(user: User): ResultAsync<User, Error>
const user: User = { name: "John" }
// Handle both cases at the end of the chain using match
const resultMessage = await validateUser(user)
.andThen(insertUser)
.match(
(user: User) => `User ${user.name} has been successfully created`,
(error: Error) => `User could not be created because ${error.message}`
)
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Effect from "effect/Effect"
interface User {
readonly name: string
}
declare function validateUser(user: User): Effect.Effect<User, Error>
declare function insertUser(user: User): Effect.Effect<User, Error>
const user: User = { name: "John" }
// Handle both cases at the end of the chain using match
const resultMessage = await Effect.runPromise(
validateUser(user).pipe(
Effect.andThen(insertUser),
Effect.match({
onSuccess: (user) =>
`User ${user.name} has been successfully created`,
onFailure: (error) =>
`User could not be created because ${error.message}`
})
)
)
```
</TabItem>
</Tabs>
### combine
**Example** (Combining multiple async results)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { ResultAsync, okAsync } from "neverthrow"
const resultList: ResultAsync<number, string>[] = [okAsync(1), okAsync(2)]
// const combinedList: ResultAsync<number[], string>
const combinedList = ResultAsync.combine(resultList)
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Effect from "effect/Effect"
const resultList: Effect.Effect<number, string>[] = [
Effect.succeed(1),
Effect.succeed(2)
]
// const combinedList: Effect<number[], string>
const combinedList = Effect.all(resultList)
```
</TabItem>
</Tabs>
### combineWithAllErrors
**Example** (Collecting all errors instead of failing fast)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { ResultAsync, okAsync, errAsync } from "neverthrow"
const resultList: ResultAsync<number, string>[] = [
okAsync(123),
errAsync("boooom!"),
okAsync(456),
errAsync("ahhhhh!")
]
const result = await ResultAsync.combineWithAllErrors(resultList)
// result is Err(['boooom!', 'ahhhhh!'])
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import { Effect, identity } from "effect"
const resultList: Effect.Effect<number, string>[] = [
Effect.succeed(123),
Effect.fail("boooom!"),
Effect.succeed(456),
Effect.fail("ahhhhh!")
]
const result = await Effect.runPromise(
Effect.either(Effect.validateAll(resultList, identity))
)
// result is left(['boooom!', 'ahhhhh!'])
```
</TabItem>
</Tabs>
## Utilities
### fromThrowable
**Example** (Safely wrapping a throwing function)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { Result } from "neverthrow"
type ParseError = { message: string }
const toParseError = (): ParseError => ({ message: "Parse Error" })
const safeJsonParse = Result.fromThrowable(JSON.parse, toParseError)
// the function can now be used safely,
// if the function throws, the result will be an Err
const result = safeJsonParse("{")
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Either from "effect/Either"
type ParseError = { message: string }
const toParseError = (): ParseError => ({ message: "Parse Error" })
const safeJsonParse = (s: string) =>
Either.try({ try: () => JSON.parse(s), catch: toParseError })
// the function can now be used safely,
// if the function throws, the result will be an Either
const result = safeJsonParse("{")
```
</TabItem>
</Tabs>
### safeTry
**Example** (Using generators to simplify error handling)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { Result, ok, safeTry } from "neverthrow"
declare function mayFail1(): Result<number, string>
declare function mayFail2(): Result<number, string>
function myFunc(): Result<number, string> {
return safeTry<number, string>(function* () {
return ok(
(yield* mayFail1().mapErr(
(e) => `aborted by an error from 1st function, ${e}`
)) +
(yield* mayFail2().mapErr(
(e) => `aborted by an error from 2nd function, ${e}`
))
)
})
}
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import * as Either from "effect/Either"
declare function mayFail1(): Either.Either<number, string>
declare function mayFail2(): Either.Either<number, string>
function myFunc(): Either.Either<number, string> {
return Either.gen(function* () {
return (
(yield* mayFail1().pipe(
Either.mapLeft(
(e) => `aborted by an error from 1st function, ${e}`
)
)) +
(yield* mayFail2().pipe(
Either.mapLeft(
(e) => `aborted by an error from 2nd function, ${e}`
)
))
)
})
}
```
</TabItem>
</Tabs>
**Note**. With `Either.gen`, you do not need to wrap the final value with `Either.right`. The generator's return value becomes the `Right`.
You can also use an async generator function with `safeTry` to represent an asynchronous block.
On the Effect side, the same pattern is written with `Effect.gen` instead of `Either.gen`.
**Example** (Using async generators to handle multiple failures)
<Tabs syncKey="effect-vs-neverthrow">
<TabItem label="neverthrow">
```ts twoslash
import { ResultAsync, safeTry, ok } from "neverthrow"
declare function mayFail1(): ResultAsync<number, string>
declare function mayFail2(): ResultAsync<number, string>
function myFunc(): ResultAsync<number, string> {
return safeTry<number, string>(async function* () {
return ok(
(yield* mayFail1().mapErr(
(e) => `aborted by an error from 1st function, ${e}`
)) +
(yield* mayFail2().mapErr(
(e) => `aborted by an error from 2nd function, ${e}`
))
)
})
}
```
</TabItem>
<TabItem label="Effect">
```ts twoslash
import { Effect } from "effect"
declare function mayFail1(): Effect.Effect<number, string>
declare function mayFail2(): Effect.Effect<number, string>
function myFunc(): Effect.Effect<number, string> {
return Effect.gen(function* () {
return (
(yield* mayFail1().pipe(
Effect.mapError(
(e) => `aborted by an error from 1st function, ${e}`
)
)) +
(yield* mayFail2().pipe(
Effect.mapError(
(e) => `aborted by an error from 2nd function, ${e}`
)
))
)
})
}
```
</TabItem>
</Tabs>
**Note**. With `Effect.gen`, you do not need to wrap the final value with `Effect.succeed`. The generator's return value becomes the `Success`.
When working with error handling in TypeScript, both neverthrow and Effect provide useful abstractions for modeling
success and failure without exceptions. They share many concepts, such as wrapping computations in a safe container,
transforming values with map, handling errors with mapErr/mapLeft, and offering utilities to combine or unwrap results.
This page shows a side-by-side comparison of neverthrow and Effect APIs for common use cases.
If you’re already familiar with neverthrow, the examples will help you understand how to achieve the same patterns with Effect.
If you’re starting fresh, the comparison highlights the similarities and differences so you can decide which library better fits your project.
neverthrow exposes instance methods (for example, result.map(...)).
Effect exposes functions on Either (for example, Either.map(result, ...)) and supports a pipe style for readability and better tree shaking.
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@param ― callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
@param ― thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
@param ― string A string to convert into a number.
@param ― radix A value between 2 and 36 that specifies the base of the number in string.
If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal.
All other strings are considered decimal.
parseInt))
9
10
constnewResult:Result<number[], Error>
newResult.
functionisOk():thisisOk<T, E>
Used to check if a Result is an OK
@returns ― true if the result is an OK variant of Result
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@param ― callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
@param ― thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
@param ― string A string to convert into a number.
@param ― radix A value between 2 and 36 that specifies the base of the number in string.
If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal.
All other strings are considered decimal.
Similar to map Except you must return a new Result.
This is useful for when you need to do a subsequent computation using the
inner T value, but that computation might fail.
Additionally, andThen is really useful as a tool to flatten a
Result<Result<A, E2>, E1> into a Result<A, E2> (see example below).
Similar to map Except you must return a new Result.
This is useful for when you need to do a subsequent computation using the
inner T value, but that computation might fail.
Additionally, andThen is really useful as a tool to flatten a
Result<Result<A, E2>, E1> into a Result<A, E2> (see example below).
Similar to map Except you must return a new Result.
This is useful for when you need to do a subsequent async computation using
the inner T value, but that computation might fail. Must return a ResultAsync
@param ― f The function that returns a ResultAsync to apply to the current
value
Use andThen when you need to run multiple actions in sequence, with the
second action depending on the result of the first. This is useful for
combining effects or handling computations that must happen in order.
Details
The second action can be:
A constant value (similar to
as
)
A function returning a value (similar to
map
)
A Promise
A function returning a Promise
An Effect
A function returning an Effect (similar to
flatMap
)
Note:andThen works well with both Option and Either types,
treating them as effects.
Example (Applying a Discount Based on Fetched Amount)
import { pipe, Effect } from"effect"
// Function to apply a discount safely to a transaction amount
constapplyDiscount= (
total:number,
discountRate:number
):Effect.Effect<number, Error> =>
discountRate ===0
? Effect.fail(newError("Discount rate cannot be zero"))
Takes two functions and an Either value, if the value is a Left the inner value is applied to the onLeft function, if the value is a Rightthe inner value is applied to theonRight` function.
Use andThen when you need to run multiple actions in sequence, with the
second action depending on the result of the first. This is useful for
combining effects or handling computations that must happen in order.
Details
The second action can be:
A constant value (similar to
as
)
A function returning a value (similar to
map
)
A Promise
A function returning a Promise
An Effect
A function returning an Effect (similar to
flatMap
)
Note:andThen works well with both Option and Either types,
treating them as effects.
Example (Applying a Discount Based on Fetched Amount)
import { pipe, Effect } from"effect"
// Function to apply a discount safely to a transaction amount
constapplyDiscount= (
total:number,
discountRate:number
):Effect.Effect<number, Error> =>
discountRate ===0
? Effect.fail(newError("Discount rate cannot be zero"))
Note. In neverthrow, asyncMap works with Promises directly.
In Effect, passing a Promise to combinators like Effect.andThen automatically lifts it into an Effect.
If the Promise rejects, the rejection is turned into an UnknownException, which is why the error type is widened to string | UnknownException.
Note. There is no exact equivalent of Result.combineWithAllErrors in Effect.
Use Array.getLefts to collect all errors and Array.getRights to collect all successes.
Asynchronous API
In the examples below we use Effect.runPromise to run an effect and return a Promise.
You can also use other APIs such as Effect.runPromiseExit, which can capture additional cases like defects (runtime errors) and interruptions.
Executes an effect and returns the result as a Promise.
Details
This function runs an effect and converts its result into a Promise. If the
effect succeeds, the Promise will resolve with the successful result. If
the effect fails, the Promise will reject with an error, which includes the
failure details of the effect.
The optional options parameter allows you to pass an AbortSignal for
cancellation, enabling more fine-grained control over asynchronous tasks.
When to Use
Use this function when you need to execute an effect and work with its result
in a promise-based system, such as when integrating with third-party
libraries that expect Promise results.
Example (Running a Successful Effect as a Promise)
@see ― runPromiseExit for a version that returns an Exit type instead
of rejecting.
@since ― 2.0.0
runPromise(
import Effect
@since ― 2.0.0
@since ― 2.0.0
@since ― 2.0.0
Effect.
consteither: <{
myData:string;
}, never, never>(self:Effect.Effect<{
myData:string;
}, never, never>) =>Effect.Effect<Either.Either<{
myData:string;
}, never>, never, never>
Encapsulates both success and failure of an Effect into an Either type.
Details
This function converts an effect that may fail into an effect that always
succeeds, wrapping the outcome in an Either type. The result will be
Either.Left if the effect fails, containing the recoverable error, or
Either.Right if it succeeds, containing the result.
Using this function, you can handle recoverable errors explicitly without
causing the effect to fail. This is particularly useful in scenarios where
you want to chain effects and manage both success and failure in the same
logical flow.
It's important to note that unrecoverable errors, often referred to as
"defects," are still thrown and not captured within the Either type. Only
failures that are explicitly represented as recoverable errors in the effect
are encapsulated.
The resulting effect cannot fail directly because all recoverable failures
are represented inside the Either type.
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
.
Example (Creating a Failed Effect)
import { Effect } from"effect"
// ┌─── Effect<never, Error, never>
// ▼
constfailure= Effect.fail(
newError("Operation failed due to network error")
)
@see ― succeed to create an effect that represents a successful value.
Executes an effect and returns the result as a Promise.
Details
This function runs an effect and converts its result into a Promise. If the
effect succeeds, the Promise will resolve with the successful result. If
the effect fails, the Promise will reject with an error, which includes the
failure details of the effect.
The optional options parameter allows you to pass an AbortSignal for
cancellation, enabling more fine-grained control over asynchronous tasks.
When to Use
Use this function when you need to execute an effect and work with its result
in a promise-based system, such as when integrating with third-party
libraries that expect Promise results.
Example (Running a Successful Effect as a Promise)
Encapsulates both success and failure of an Effect into an Either type.
Details
This function converts an effect that may fail into an effect that always
succeeds, wrapping the outcome in an Either type. The result will be
Either.Left if the effect fails, containing the recoverable error, or
Either.Right if it succeeds, containing the result.
Using this function, you can handle recoverable errors explicitly without
causing the effect to fail. This is particularly useful in scenarios where
you want to chain effects and manage both success and failure in the same
logical flow.
It's important to note that unrecoverable errors, often referred to as
"defects," are still thrown and not captured within the Either type. Only
failures that are explicitly represented as recoverable errors in the effect
are encapsulated.
The resulting effect cannot fail directly because all recoverable failures
are represented inside the Either type.
Creates an Effect that represents an asynchronous computation that might
fail.
When to Use
In situations where you need to perform asynchronous operations that might
fail, such as fetching data from an API, you can use the tryPromise
constructor. This constructor is designed to handle operations that could
throw exceptions by capturing those exceptions and transforming them into
manageable errors.
Error Handling
There are two ways to handle errors with tryPromise:
If you don't provide a catch function, the error is caught and the
effect fails with an UnknownException.
If you provide a catch function, the error is caught and the catch
function maps it to an error of type E.
Interruptions
An optional AbortSignal can be provided to allow for interruption of the
wrapped Promise API.
Example (Fetching a TODO Item)
import { Effect } from"effect"
constgetTodo= (id:number) =>
// Will catch any errors and propagate them as UnknownException
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@param ― callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
@param ― thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
map((
user: User
user) =>
user: User
user.
User.name: string
name)
14
)
15
16
// We can extract the Result using .then() or await
Attaches callbacks for the resolution and/or rejection of the Promise.
@param ― onfulfilled The callback to execute when the Promise is resolved.
@param ― onrejected The callback to execute when the Promise is rejected.
@returns ― A Promise for the completion of which ever callback is executed.
then((
namesResult: Result<string[], Error>
namesResult:
typeResult<T, E> =Ok<T, E> |Err<T, E>
Result<
interfaceArray<T>
Array<string>,
interfaceError
Error>) => {
18
if (
namesResult: Result<string[], Error>
namesResult.
functionisErr():thisisErr<T, E>
Used to check if a Result is an Err
@returns ― true if the result is an Err variant of Result
isErr()) {
19
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
Adds all the elements of an array into a string, separated by the specified separator string.
@param ― separator A string used to separate one element of the array from the next in the resulting string. If omitted, the array elements are separated with a comma.
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.
map takes a function and applies it to the value contained within an
effect, creating a new effect with the transformed value.
It's important to note that effects are immutable, meaning that the original
effect is not modified. Instead, a new effect is returned with the updated
value.
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@param ― callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
@param ― thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
Executes an effect and returns the result as a Promise.
Details
This function runs an effect and converts its result into a Promise. If the
effect succeeds, the Promise will resolve with the successful result. If
the effect fails, the Promise will reject with an error, which includes the
failure details of the effect.
The optional options parameter allows you to pass an AbortSignal for
cancellation, enabling more fine-grained control over asynchronous tasks.
When to Use
Use this function when you need to execute an effect and work with its result
in a promise-based system, such as when integrating with third-party
libraries that expect Promise results.
Example (Running a Successful Effect as a Promise)
Encapsulates both success and failure of an Effect into an Either type.
Details
This function converts an effect that may fail into an effect that always
succeeds, wrapping the outcome in an Either type. The result will be
Either.Left if the effect fails, containing the recoverable error, or
Either.Right if it succeeds, containing the result.
Using this function, you can handle recoverable errors explicitly without
causing the effect to fail. This is particularly useful in scenarios where
you want to chain effects and manage both success and failure in the same
logical flow.
It's important to note that unrecoverable errors, often referred to as
"defects," are still thrown and not captured within the Either type. Only
failures that are explicitly represented as recoverable errors in the effect
are encapsulated.
The resulting effect cannot fail directly because all recoverable failures
are represented inside the Either type.
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
Adds all the elements of an array into a string, separated by the specified separator string.
@param ― separator A string used to separate one element of the array from the next in the resulting string. If omitted, the array elements are separated with a comma.
Attaches callbacks for the resolution and/or rejection of the Promise.
@param ― onfulfilled The callback to execute when the Promise is resolved.
@param ― onrejected The callback to execute when the Promise is rejected.
@returns ― A Promise for the completion of which ever callback is executed.
then((
usersResult: Result<User[], string>
usersResult:
typeResult<T, E> =Ok<T, E> |Err<T, E>
Result<
interfaceArray<T>
Array<
interfaceUser
User>, string>) => {
20
if (
usersResult: Result<User[], string>
usersResult.
functionisErr():thisisErr<T, E>
Used to check if a Result is an Err
@returns ― true if the result is an Err variant of Result
isErr()) {
21
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
Adds all the elements of an array into a string, separated by the specified separator string.
@param ― separator A string used to separate one element of the array from the next in the resulting string. If omitted, the array elements are separated with a comma.
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.
@since ― 2.0.0
@since ― 2.0.0
Effect<
interfaceArray<T>
Array<
interfaceUser
User>,
interfaceError
Error>
10
11
const
constusersInCanada:Effect.Effect<User[], "Unknown country"|"System error, please contact an administrator.", never>
Transforms or modifies the error produced by an effect without affecting its
success value.
When to Use
This function is helpful when you want to enhance the error with additional
information, change the error type, or apply custom error handling while
keeping the original behavior of the effect's success values intact. It only
operates on the error channel and leaves the success channel unchanged.
} |undefined) =>Promise<Either.Either<User[], "Unknown country"|"System error, please contact an administrator.">>
Executes an effect and returns the result as a Promise.
Details
This function runs an effect and converts its result into a Promise. If the
effect succeeds, the Promise will resolve with the successful result. If
the effect fails, the Promise will reject with an error, which includes the
failure details of the effect.
The optional options parameter allows you to pass an AbortSignal for
cancellation, enabling more fine-grained control over asynchronous tasks.
When to Use
Use this function when you need to execute an effect and work with its result
in a promise-based system, such as when integrating with third-party
libraries that expect Promise results.
Example (Running a Successful Effect as a Promise)
@see ― runPromiseExit for a version that returns an Exit type instead
of rejecting.
@since ― 2.0.0
runPromise(
import Effect
@since ― 2.0.0
@since ― 2.0.0
@since ― 2.0.0
Effect.
consteither: <User[], "Unknown country"|"System error, please contact an administrator.", never>(self:Effect.Effect<User[], "Unknown country"|"System error, please contact an administrator.", never>) =>Effect.Effect<Either.Either<User[], "Unknown country"|"System error, please contact an administrator.">, never, never>
Encapsulates both success and failure of an Effect into an Either type.
Details
This function converts an effect that may fail into an effect that always
succeeds, wrapping the outcome in an Either type. The result will be
Either.Left if the effect fails, containing the recoverable error, or
Either.Right if it succeeds, containing the result.
Using this function, you can handle recoverable errors explicitly without
causing the effect to fail. This is particularly useful in scenarios where
you want to chain effects and manage both success and failure in the same
logical flow.
It's important to note that unrecoverable errors, often referred to as
"defects," are still thrown and not captured within the Either type. Only
failures that are explicitly represented as recoverable errors in the effect
are encapsulated.
The resulting effect cannot fail directly because all recoverable failures
are represented inside the Either type.
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
Adds all the elements of an array into a string, separated by the specified separator string.
@param ― separator A string used to separate one element of the array from the next in the resulting string. If omitted, the array elements are separated with a comma.
join(","))
31
}
32
}
33
)
unwrapOr
Example (Providing a default value when async fails)
Executes an effect and returns the result as a Promise.
Details
This function runs an effect and converts its result into a Promise. If the
effect succeeds, the Promise will resolve with the successful result. If
the effect fails, the Promise will reject with an error, which includes the
failure details of the effect.
The optional options parameter allows you to pass an AbortSignal for
cancellation, enabling more fine-grained control over asynchronous tasks.
When to Use
Use this function when you need to execute an effect and work with its result
in a promise-based system, such as when integrating with third-party
libraries that expect Promise results.
Example (Running a Successful Effect as a Promise)
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
.
Example (Creating a Failed Effect)
import { Effect } from"effect"
// ┌─── Effect<never, Error, never>
// ▼
constfailure= Effect.fail(
newError("Operation failed due to network error")
)
@see ― succeed to create an effect that represents a successful value.
constorElseSucceed: <number>(evaluate:LazyArg<number>) => <A, E, R>(self:Effect.Effect<A, E, R>) =>Effect.Effect<number|A, never, R> (+1overload)
Ensures the effect always succeeds by replacing failures with a default
success value.
Details
This function transforms an effect that may fail into one that cannot fail by
replacing any failure with a provided success value. If the original effect
fails, the failure is "swallowed," and the specified success value is
returned instead. If the original effect succeeds, its value remains
unchanged.
When to Use
This is especially useful for providing default values in case of failure,
ensuring that an effect always completes successfully. By using this
function, you can avoid the need for complex error handling and guarantee a
fallback result.
Attaches callbacks for the resolution and/or rejection of the Promise.
@param ― onfulfilled The callback to execute when the Promise is resolved.
@param ― onrejected The callback to execute when the Promise is rejected.
@returns ― A Promise for the completion of which ever callback is executed.
then((
res: Result<void, Error>
res:
typeResult<T, E> =Ok<T, E> |Err<T, E>
Result<void,
interfaceError
Error>) => {
15
if (
res: Result<void, Error>
res.
functionisErr():thisisErr<T, E>
Used to check if a Result is an Err
@returns ― true if the result is an Err variant of Result
isErr()) {
16
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
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.
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.
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.
Use andThen when you need to run multiple actions in sequence, with the
second action depending on the result of the first. This is useful for
combining effects or handling computations that must happen in order.
Details
The second action can be:
A constant value (similar to
as
)
A function returning a value (similar to
map
)
A Promise
A function returning a Promise
An Effect
A function returning an Effect (similar to
flatMap
)
Note:andThen works well with both Option and Either types,
treating them as effects.
Example (Applying a Discount Based on Fetched Amount)
import { pipe, Effect } from"effect"
// Function to apply a discount safely to a transaction amount
constapplyDiscount= (
total:number,
discountRate:number
):Effect.Effect<number, Error> =>
discountRate ===0
? Effect.fail(newError("Discount rate cannot be zero"))
Use andThen when you need to run multiple actions in sequence, with the
second action depending on the result of the first. This is useful for
combining effects or handling computations that must happen in order.
Details
The second action can be:
A constant value (similar to
as
)
A function returning a value (similar to
map
)
A Promise
A function returning a Promise
An Effect
A function returning an Effect (similar to
flatMap
)
Note:andThen works well with both Option and Either types,
treating them as effects.
Example (Applying a Discount Based on Fetched Amount)
import { pipe, Effect } from"effect"
// Function to apply a discount safely to a transaction amount
constapplyDiscount= (
total:number,
discountRate:number
):Effect.Effect<number, Error> =>
discountRate ===0
? Effect.fail(newError("Discount rate cannot be zero"))
Executes an effect and returns the result as a Promise.
Details
This function runs an effect and converts its result into a Promise. If the
effect succeeds, the Promise will resolve with the successful result. If
the effect fails, the Promise will reject with an error, which includes the
failure details of the effect.
The optional options parameter allows you to pass an AbortSignal for
cancellation, enabling more fine-grained control over asynchronous tasks.
When to Use
Use this function when you need to execute an effect and work with its result
in a promise-based system, such as when integrating with third-party
libraries that expect Promise results.
Example (Running a Successful Effect as a Promise)
Encapsulates both success and failure of an Effect into an Either type.
Details
This function converts an effect that may fail into an effect that always
succeeds, wrapping the outcome in an Either type. The result will be
Either.Left if the effect fails, containing the recoverable error, or
Either.Right if it succeeds, containing the result.
Using this function, you can handle recoverable errors explicitly without
causing the effect to fail. This is particularly useful in scenarios where
you want to chain effects and manage both success and failure in the same
logical flow.
It's important to note that unrecoverable errors, often referred to as
"defects," are still thrown and not captured within the Either type. Only
failures that are explicitly represented as recoverable errors in the effect
are encapsulated.
The resulting effect cannot fail directly because all recoverable failures
are represented inside the Either type.
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
Attaches callbacks for the resolution and/or rejection of the Promise.
@param ― onfulfilled The callback to execute when the Promise is resolved.
@param ― onrejected The callback to execute when the Promise is rejected.
@returns ― A Promise for the completion of which ever callback is executed.
then((
result: Result<User, never>
result) => {
15
if (
result: Result<User, never>
result.
functionisOk():thisisOk<T, E>
Used to check if a Result is an OK
@returns ― true if the result is an OK variant of Result
isOk()) {
16
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
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.
@since ― 2.0.0
@since ― 2.0.0
Effect<
interfaceUser
User,
interfaceError
Error>
6
declarefunction
functiongetDefaultUser():User
getDefaultUser():
interfaceUser
User
7
8
const
constuserId:"123"
userId="123"
9
10
// Try to fetch user data, but provide a default if it fails
constorElse: <User, never, never>(that:LazyArg<Effect.Effect<User, never, never>>) => <A, E, R>(self:Effect.Effect<A, E, R>) =>Effect.Effect<User|A, never, R> (+1overload)
Attempts one effect, and if it fails, falls back to another effect.
Details
This function allows you to try executing an effect, and if it fails
(produces an error), a fallback effect is executed instead. The fallback
effect is defined as a lazy argument, meaning it will only be evaluated if
the first effect fails. This provides a way to recover from errors by
specifying an alternative path of execution.
The error type of the resulting effect will be that of the fallback effect,
as the first effect's error is replaced when the fallback is executed.
Example
import { Effect } from"effect"
constsuccess= Effect.succeed("success")
constfailure= Effect.fail("failure")
constfallback= Effect.succeed("fallback")
// Try the success effect first, fallback is not used
Executes an effect and returns the result as a Promise.
Details
This function runs an effect and converts its result into a Promise. If the
effect succeeds, the Promise will resolve with the successful result. If
the effect fails, the Promise will reject with an error, which includes the
failure details of the effect.
The optional options parameter allows you to pass an AbortSignal for
cancellation, enabling more fine-grained control over asynchronous tasks.
When to Use
Use this function when you need to execute an effect and work with its result
in a promise-based system, such as when integrating with third-party
libraries that expect Promise results.
Example (Running a Successful Effect as a Promise)
Encapsulates both success and failure of an Effect into an Either type.
Details
This function converts an effect that may fail into an effect that always
succeeds, wrapping the outcome in an Either type. The result will be
Either.Left if the effect fails, containing the recoverable error, or
Either.Right if it succeeds, containing the result.
Using this function, you can handle recoverable errors explicitly without
causing the effect to fail. This is particularly useful in scenarios where
you want to chain effects and manage both success and failure in the same
logical flow.
It's important to note that unrecoverable errors, often referred to as
"defects," are still thrown and not captured within the Either type. Only
failures that are explicitly represented as recoverable errors in the effect
are encapsulated.
The resulting effect cannot fail directly because all recoverable failures
are represented inside the Either type.
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
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.
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.
@since ― 2.0.0
@since ― 2.0.0
Effect<
interfaceUser
User,
interfaceError
Error>
8
9
const
constuser:User
user:
interfaceUser
User= {
User.name: string
name: "John" }
10
11
// Handle both cases at the end of the chain using match
Executes an effect and returns the result as a Promise.
Details
This function runs an effect and converts its result into a Promise. If the
effect succeeds, the Promise will resolve with the successful result. If
the effect fails, the Promise will reject with an error, which includes the
failure details of the effect.
The optional options parameter allows you to pass an AbortSignal for
cancellation, enabling more fine-grained control over asynchronous tasks.
When to Use
Use this function when you need to execute an effect and work with its result
in a promise-based system, such as when integrating with third-party
libraries that expect Promise results.
Example (Running a Successful Effect as a Promise)
Use andThen when you need to run multiple actions in sequence, with the
second action depending on the result of the first. This is useful for
combining effects or handling computations that must happen in order.
Details
The second action can be:
A constant value (similar to
as
)
A function returning a value (similar to
map
)
A Promise
A function returning a Promise
An Effect
A function returning an Effect (similar to
flatMap
)
Note:andThen works well with both Option and Either types,
treating them as effects.
Example (Applying a Discount Based on Fetched Amount)
import { pipe, Effect } from"effect"
// Function to apply a discount safely to a transaction amount
constapplyDiscount= (
total:number,
discountRate:number
):Effect.Effect<number, Error> =>
discountRate ===0
? Effect.fail(newError("Discount rate cannot be zero"))
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.
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.
Combines multiple effects into one, returning results based on the input
structure.
Details
Use this function when you need to run multiple effects and combine their
results into a single output. It supports tuples, iterables, structs, and
records, making it flexible for different input types.
For instance, if the input is a tuple:
// ┌─── a tuple of effects
// ▼
Effect.all([effect1, effect2, ...])
the effects are executed sequentially, and the result is a new effect
containing the results as a tuple. The results in the tuple match the order
of the effects passed to Effect.all.
Concurrency
You can control the execution order (e.g., sequential vs. concurrent) using
the concurrency option.
Short-Circuiting Behavior
This function stops execution on the first error it encounters, this is
called "short-circuiting". If any effect in the collection fails, the
remaining effects will not run, and the error will be propagated. To change
this behavior, you can use the mode option, which allows all effects to run
and collect results as Either or Option.
The mode option
The { mode: "either" } option changes the behavior of Effect.all to
ensure all effects run, even if some fail. Instead of stopping on the first
failure, this mode collects both successes and failures, returning an array
of Either instances where each result is either a Right (success) or a
Left (failure).
Similarly, the { mode: "validate" } option uses Option to indicate
success or failure. Each effect returns None for success and Some with
the error for failure.
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.
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
.
Example (Creating a Failed Effect)
import { Effect } from"effect"
// ┌─── Effect<never, Error, never>
// ▼
constfailure= Effect.fail(
newError("Operation failed due to network error")
)
@see ― succeed to create an effect that represents a successful value.
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
.
Example (Creating a Failed Effect)
import { Effect } from"effect"
// ┌─── Effect<never, Error, never>
// ▼
constfailure= Effect.fail(
newError("Operation failed due to network error")
)
@see ― succeed to create an effect that represents a successful value.
Executes an effect and returns the result as a Promise.
Details
This function runs an effect and converts its result into a Promise. If the
effect succeeds, the Promise will resolve with the successful result. If
the effect fails, the Promise will reject with an error, which includes the
failure details of the effect.
The optional options parameter allows you to pass an AbortSignal for
cancellation, enabling more fine-grained control over asynchronous tasks.
When to Use
Use this function when you need to execute an effect and work with its result
in a promise-based system, such as when integrating with third-party
libraries that expect Promise results.
Example (Running a Successful Effect as a Promise)
Encapsulates both success and failure of an Effect into an Either type.
Details
This function converts an effect that may fail into an effect that always
succeeds, wrapping the outcome in an Either type. The result will be
Either.Left if the effect fails, containing the recoverable error, or
Either.Right if it succeeds, containing the result.
Using this function, you can handle recoverable errors explicitly without
causing the effect to fail. This is particularly useful in scenarios where
you want to chain effects and manage both success and failure in the same
logical flow.
It's important to note that unrecoverable errors, often referred to as
"defects," are still thrown and not captured within the Either type. Only
failures that are explicitly represented as recoverable errors in the effect
are encapsulated.
The resulting effect cannot fail directly because all recoverable failures
are represented inside the Either type.
Applies an effectful operation to each element in a collection while
collecting both successes and failures.
Details
This function allows you to apply an effectful operation to every item in a
collection.
Unlike
forEach
, which would stop at the first error, this function
continues processing all elements, accumulating both successes and failures.
When to Use
Use this function when you want to process every item in a collection, even
if some items fail. This is particularly useful when you need to perform
operations on all elements without halting due to an error.
Keep in mind that if there are any failures, all successes will be lost,
so this function is not suitable when you need to keep the successful results
in case of errors.
Wraps a function with a try catch, creating a new function with the same
arguments but returning Ok if successful, Err if the function throws
@param ― fn function to wrap with ok on success or err on failure
@param ― errorFn when an error is thrown, this will wrap the error result if provided
fromThrowable(
varJSON:JSON
An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.
JSON.
JSON.parse(text: string, reviver?: (this:any, key:string, value:any) => any): any
Converts a JavaScript Object Notation (JSON) string into an object.
@param ― text A valid JSON string.
@param ― reviver A function that transforms the results. This function is called for each member of the object.
If a member contains nested objects, the nested objects are transformed before the parent object is.
@throws ― {SyntaxError} If text is not valid JSON.
parse,
consttoParseError: () =>ParseError
toParseError)
7
8
// the function can now be used safely,
9
// if the function throws, the result will be an Err
An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.
JSON.
JSON.parse(text: string, reviver?: (this:any, key:string, value:any) => any): any
Converts a JavaScript Object Notation (JSON) string into an object.
@param ― text A valid JSON string.
@param ― reviver A function that transforms the results. This function is called for each member of the object.
If a member contains nested objects, the nested objects are transformed before the parent object is.
@throws ― {SyntaxError} If text is not valid JSON.
parse(
s: string
s),
catch: (error:unknown) => ParseError
catch:
consttoParseError: () =>ParseError
toParseError })
8
9
// the function can now be used safely,
10
// if the function throws, the result will be an Either
Maps the Left side of an Either value to a new Either value.
@since ― 2.0.0
mapLeft(
16
(
e: string
e) =>`aborted by an error from 2nd function, ${
e: string
e}`
17
)
18
))
19
)
20
})
21
}
Note. With Either.gen, you do not need to wrap the final value with Either.right. The generator’s return value becomes the Right.
You can also use an async generator function with safeTry to represent an asynchronous block.
On the Effect side, the same pattern is written with Effect.gen instead of Either.gen.
Example (Using async generators to handle multiple failures)
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.
@since ― 2.0.0
@since ― 2.0.0
Effect<number, string>
4
declarefunction
functionmayFail2():Effect.Effect<number, string>
mayFail2():
import Effect
@since ― 2.0.0
@since ― 2.0.0
@since ― 2.0.0
Effect.
interfaceEffect<outA, outE=never, outR=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.
@since ― 2.0.0
@since ― 2.0.0
Effect<number, string>
5
6
function
functionmyFunc():Effect.Effect<number, string>
myFunc():
import Effect
@since ― 2.0.0
@since ― 2.0.0
@since ― 2.0.0
Effect.
interfaceEffect<outA, outE=never, outR=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.
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to Use
Effect.gen allows you to write code that looks and behaves like synchronous
code, but it can handle asynchronous tasks, errors, and complex control flow
(like loops and conditions). It helps make asynchronous code more readable
and easier to manage.
The generator functions work similarly to async/await but with more
explicit control over the execution of effects. You can yield* values from
effects and return the final result at the end.
Transforms or modifies the error produced by an effect without affecting its
success value.
When to Use
This function is helpful when you want to enhance the error with additional
information, change the error type, or apply custom error handling while
keeping the original behavior of the effect's success values intact. It only
operates on the error channel and leaves the success channel unchanged.
Transforms or modifies the error produced by an effect without affecting its
success value.
When to Use
This function is helpful when you want to enhance the error with additional
information, change the error type, or apply custom error handling while
keeping the original behavior of the effect's success values intact. It only
operates on the error channel and leaves the success channel unchanged.