Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

From Discord: Proposing a Effect.flatMapError Function #621

Open
effect-bot opened this issue Aug 24, 2023 · 1 comment
Open

From Discord: Proposing a Effect.flatMapError Function #621

effect-bot opened this issue Aug 24, 2023 · 1 comment

Comments

@effect-bot
Copy link

Summary

The proposed flatMapError function would take an effect self and a mapping function fn that transforms the error type E to a new effect. The function signature can be either:

function flatMapError<R, E, A, R2, E2>(self: Effect<R, E, A>, fn: (e: E) => Effect<R2, never, E2>): Effect<R | R2, E2, A>

or

function flatMapError<R, E, A, R2, E2, E3>(self: Effect<R, E, A>, fn: (e: E) => Effect<R2, E2, E3>): Effect<R | R2, E2 | E3, A>

The key takeaway is that the flatMapError function allows you to handle errors from an effect and transform them into a new effect. This can be useful for error recovery or for chaining effects that may produce different error types.

Example article

Proposing a Effect.flatMapError Function

The Effect.flatMapError function is a proposed addition to the Effect-TS ecosystem. It allows you to handle errors in a more flexible way by providing a mapping function that transforms the error type of an effect.

Function Signature

The function signature of Effect.flatMapError is as follows:

function flatMapError<R, E, A, R2, E2>(self: Effect<R, E, A>, fn: (e: E) => Effect<R2, never, E2>): Effect<R | R2, E2, A>

This function takes an effect self with an error type E, and a mapping function fn that takes an error of type E and returns a new effect with an error type E2. The resulting effect has the same success type A as the original effect.

Example Usage

Here's an example of how you can use Effect.flatMapError:

import { Effect } from '@effect/io'

// An effect that may fail with an error
const effect: Effect<unknown, string, number> = Effect.fail('Oops!')

// A mapping function that transforms the error type
const mappingFn = (error: string) => Effect.succeed(error.length)

// Using flatMapError to handle the error
const result = Effect.flatMapError(effect, mappingFn)

// Running the effect and handling the result
result.run().then(console.log) // Output: 5

In this example, the effect can fail with an error of type string. We define a mapping function mappingFn that takes the error message and returns a new effect that succeeds with the length of the error message. We use Effect.flatMapError to apply the mapping function to the original effect, resulting in a new effect with the transformed error type. Finally, we run the effect and handle the result.

Handling Eventually Raised Errors

One question that arises is how Effect.flatMapError should handle eventually raised errors from the effect returned by the mapping function. One approach is to force the effect to never raise errors by using never as the error type. This ensures that any errors raised by the mapping function are treated as defects and cause the effect to fail.

import { Effect } from '@effect/io'

const effect: Effect<unknown, string, number> = Effect.fail('Oops!')

const mappingFn = (error: string) => Effect.fail(`Mapping error: ${error}`)

const result = Effect.flatMapError(effect, mappingFn)

result.run().catch(console.error) // Output: Mapping error: Oops!

In this example, the mapping function mappingFn returns an effect that fails with a new error message. Since we use never as the error type for the effect returned by mappingFn, any errors raised by that effect are treated as defects and cause the overall effect to fail.

Conclusion

The proposed Effect.flatMapError function provides a convenient way to handle errors in a flexible manner by allowing you to transform the error type of an effect. This can be useful in scenarios where you need to handle errors in a specific way or perform additional computations based on the error.

Discord thread

https://discord.com/channels/795981131316985866/1144164954526715964

@tminich
Copy link

tminich commented Sep 5, 2023

Isn't that exactly what Effect.catchAll does?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants