A doubt still remains: did we really handled all errors? What if something else goes wrong?
All the errors that we defined and collected in the Effect
type are called Expected errors.
Expected errors (also called failures, typed errors or recoverable errors) are errors that developers anticipate as part of the normal program execution.
The catchTags
function is in fact designed to recover from expected errors:
const main = fetchRequest.pipe(
Effect.flatMap(jsonResponse)
);
FetchError
and JsonError
are expected errors. As such they are tracked inside the Effect
type: Effect<unknown, FetchError | JsonError>
.
const main = fetchRequest.pipe(
Effect.flatMap(jsonResponse),
Effect.catchTags({
FetchError: () => Effect.succeed("Fetch error"),
JsonError: () => Effect.succeed("Json error"),
})
);
Here we recover from both FetchError
and JsonError
by returning a string
. Since we recovered from these errors, they are removed from the Effect
type: Effect<unknown, never>
.
But there is another category of errors: Unexpected errors (also called defects, untyped errors, or unrecoverable errors).
Unexpected errors in effect
When working with software a lot of unexpected situations can happen:
- The server crashes
- The memory is full
- The internet connection suddenly disappears
These are errors that developers do not anticipate occurring during normal program execution.
Since these errors are not expected,
Effect
does not track them at the type level.
However, the Effect runtime does keep track of these errors and provides several methods to aid in recovering from unexpected errors.
Effect internally never loses any information about the program execution.
All errors are collected inside the Cause
module:
export type Cause<E> = Empty | Fail<E> | Die | Interrupt | Sequential<E> | Parallel<E>
Effect offers various APIs to access, inspect, and recover from expected and unexpected errors.
Let's learn about the first of them: Exit
.