Yieldable Errors
"Yieldable Errors" are special types of errors that can be yielded within a generator function used by Effect.gen
. The unique feature of these errors is that you don't need to use the Effect.fail
API explicitly to handle them. They offer a more intuitive and convenient way to work with custom errors in your code.
Data.Error
The Data.Error
constructor enables you to create a base yieldable error class. This class can be used to represent different types of errors in your code. Here's how you can use it:
import { Effect, Data } from "effect"
class MyError extends Data.Error<{ message: string }> {}
// $ExpectType Effect<never, MyError, void>
export const program = Effect.gen(function* (_) {
yield* _(new MyError({ message: "Oh no!" })) // same as yield* _(Effect.fail(new MyError({ message: "Oh no!" })))
})
Effect.runPromise(program).then(console.log, console.error)
/*
Output:
{
_id: "FiberFailure",
cause: {
_id: "Cause",
_tag: "Fail",
reason: 'Oh no!'
failure: MyError: "Oh no!
at ...
}
}
*/
Data.TaggedError
The Data.TaggedError
constructor is useful for creating tagged yieldable errors. These errors bear a distinct property named _tag
, which acts as their unique identifier, allowing you to differentiate them from one another. Here's how you can use it:
import { Effect, Data, Random } from "effect"
// An error with _tag: "Foo"
class FooError extends Data.TaggedError("Foo")<{
message: string
}> {}
// An error with _tag: "Bar"
class BarError extends Data.TaggedError("Bar")<{
randomNumber: number
}> {}
// $ExpectType Effect<never, never, string>
export const program = Effect.gen(function* (_) {
const n = yield* _(Random.next)
return n > 0.5
? "yay!"
: n < 0.2
? yield* _(new FooError({ message: "Oh no!" }))
: yield* _(new BarError({ randomNumber: n }))
}).pipe(
Effect.catchTags({
Foo: (error) => Effect.succeed(`Foo error: ${error.message}`),
Bar: (error) => Effect.succeed(`Bar error: ${error.randomNumber}`)
})
)
Effect.runPromise(program).then(console.log, console.error)
/*
Example Output (n < 0.2):
Foo error: Oh no!
*/
In this example, we create FooError
and BarError
classes with distinct tags ("Foo" and "Bar"). These tags help identify the type of error when handling errors in your code.