In Effect you can perform various operations on the error channel of effects. These operations allow you to transform, inspect, and handle errors in different ways. Let’s explore some of these operations.
Map Operations
mapError
The Effect.mapError function is used when you need to transform or modify an error produced by an effect, without affecting the success value. This can be helpful when you want to add extra information to the error or change its type.
Example (Mapping an Error)
Here, the error type changes from string to Error.
mapBoth
The Effect.mapBoth function allows you to apply transformations to both channels: the error channel and the success channel of an effect. It takes two map functions as arguments: one for the error channel and the other for the success channel.
Example (Mapping Both Success and Error)
Filtering the Success Channel
The Effect library provides several operators to filter values on the success channel based on a given predicate.
These operators offer different strategies for handling cases where the predicate fails:
API
Description
filterOrFail
This operator filters the values on the success channel based on a predicate. If the predicate fails for any value, the original effect fails with an error.
filterOrDie / filterOrDieMessage
These operators also filter the values on the success channel based on a predicate. If the predicate fails for any value, the original effect terminates abruptly. The filterOrDieMessage variant allows you to provide a custom error message.
filterOrElse
This operator filters the values on the success channel based on a predicate. If the predicate fails for any value, an alternative effect is executed instead.
Example (Filtering Success Values)
It’s important to note that depending on the specific filtering operator used, the effect can either fail, terminate abruptly, or execute an alternative effect when the predicate fails. Choose the appropriate operator based on your desired error handling strategy and program logic.
The filtering APIs can also be combined with user-defined type guards to improve type safety and code clarity. This ensures that only valid types pass through.
Example (Using a Type Guard)
In the example above, a guard is used within the filterOrFail API to ensure that the user is of type User rather than User | null.
If you prefer, you can utilize a pre-made guard like Predicate.isNotNull for simplicity and consistency.
Inspecting Errors
Similar to tapping for success values, Effect provides several operators for inspecting error values.
These operators allow developers to observe failures or underlying issues without modifying the outcome.
tapError
Executes an effectful operation to inspect the failure of an effect without altering it.
Example (Inspecting Errors)
tapErrorTag
This function allows you to inspect errors that match a specific tag, helping you handle different error types more precisely.
Example (Inspecting Tagged Errors)
tapErrorCause
This function inspects the complete cause of an error, including failures and defects.
Example (Inspecting Error Causes)
tapDefect
Specifically inspects non-recoverable failures or defects in an effect (i.e., one or more Die causes).
Example (Inspecting Defects)
tapBoth
Inspects both success and failure outcomes of an effect, performing different actions based on the result.
Example (Inspecting Both Success and Failure)
Exposing Errors in The Success Channel
The Effect.either function transforms an Effect<A, E, R> into an effect that encapsulates both potential failure and success within an Either data type:
This means if you have an effect with the following type:
and you call Effect.either on it, the type becomes:
The resulting effect cannot fail because the potential failure is now represented within the Either’s Left type.
The error type of the returned Effect is specified as never, confirming that the effect is structured to not fail.
This function becomes especially useful when recovering from effects that may fail when using Effect.gen:
Example (Using Effect.either to Handle Errors)
Exposing the Cause in The Success Channel
You can use the Effect.cause function to expose the cause of an effect, which is a more detailed representation of failures, including error messages and defects.
Example (Logging the Cause of Failure)
Merging the Error Channel into the Success Channel
The Effect.merge function allows you to combine the error channel with the success channel. This results in an effect that never fails; instead, both successes and errors are handled as values in the success channel.
Example (Combining Error and Success Channels)
Flipping Error and Success Channels
The Effect.flip function allows you to switch the error and success channels of an effect. This means that what was previously a success becomes the error, and vice versa.