Yieldable Errors
On this page
"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:
ts
import {Effect ,Data } from "effect"classMyError extendsData .Error <{message : string }> {}export constprogram =Effect .gen (function* (_ ) {yield*_ (newMyError ({message : "Oh no!" })) // same as yield* _(Effect.fail(new MyError({ message: "Oh no!" })))})Effect .runPromiseExit (program ).then (console .log )/*Output:{_id: 'Exit',_tag: 'Failure',cause: { _id: 'Cause', _tag: 'Fail', failure: { message: 'Oh no!' } }}*/
ts
import {Effect ,Data } from "effect"classMyError extendsData .Error <{message : string }> {}export constprogram =Effect .gen (function* (_ ) {yield*_ (newMyError ({message : "Oh no!" })) // same as yield* _(Effect.fail(new MyError({ message: "Oh no!" })))})Effect .runPromiseExit (program ).then (console .log )/*Output:{_id: 'Exit',_tag: 'Failure',cause: { _id: 'Cause', _tag: 'Fail', failure: { message: 'Oh no!' } }}*/
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:
ts
import {Effect ,Data ,Random } from "effect"// An error with _tag: "Foo"classFooError extendsData .TaggedError ("Foo")<{message : string}> {}// An error with _tag: "Bar"classBarError extendsData .TaggedError ("Bar")<{randomNumber : number}> {}export constprogram =Effect .gen (function* (_ ) {constn = yield*_ (Random .next )returnn > 0.5? "yay!":n < 0.2? yield*_ (newFooError ({message : "Oh no!" })): yield*_ (newBarError ({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!*/
ts
import {Effect ,Data ,Random } from "effect"// An error with _tag: "Foo"classFooError extendsData .TaggedError ("Foo")<{message : string}> {}// An error with _tag: "Bar"classBarError extendsData .TaggedError ("Bar")<{randomNumber : number}> {}export constprogram =Effect .gen (function* (_ ) {constn = yield*_ (Random .next )returnn > 0.5? "yay!":n < 0.2? yield*_ (newFooError ({message : "Oh no!" })): yield*_ (newBarError ({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.