catchTags: Catch multiple errors

Collecting different types of errors becomes useful when doing error handling with catchTag.

We can now catch a specific error from its _tag:

const main = fetchRequest.pipe(
  Effect.flatMap(jsonResponse),
  Effect.catchTag("FetchError", () => Effect.succeed("Fetch error"))
);

Notice how the first parameter of catchTag uses the _tag string literal from our custom error to distinguish between errors.

What's even better here is that effect removed FetchError from the error parameter since we handled that error. We are therefore left with only JsonError.

/// Effect<unknown, JsonError>
const main = fetchRequest.pipe(
  Effect.flatMap(jsonResponse),
  Effect.catchTag("FetchError", () => Effect.succeed("Fetch error"))
);

In practice this means that we always know from the type what errors can happen.

After an error is handled, it will disappear from the type. In summary:

  • Any Effect error is added to the type
  • Any error handled using catchTag is removed from the type

We can then handle JsonError with another catchTag:

/// Effect<unknown, never>
const main = fetchRequest.pipe(
  Effect.flatMap(jsonResponse),
  Effect.catchTag("FetchError", () => Effect.succeed("Fetch error")),
  Effect.catchTag("JsonError", () => Effect.succeed("Json error"))
);

Now the error parameter is empty (never), we handled all the errors and we are ready to run the program.

Catching multiple errors at once

When we need to catch multiple errors we can use Effect.catchTags:

All the error tags can be autocompleted by your IDE. That's the benefit of using types to guide development.

All the error tags appear in the autocomplete suggestions in the IDE. No need to manually check errors and tags
All the error tags appear in the autocomplete suggestions in the IDE. No need to manually check errors and tags

/// Effect<unknown, never>
const main = fetchRequest.pipe(
  Effect.flatMap(jsonResponse),
  Effect.catchTags({
    FetchError: () => Effect.succeed("Fetch error"),
    JsonError: () => Effect.succeed("Json error"),
  })
);
Effect Playground

With this we solved error handling!

These APIs are enough to define and handle errors:

  • tryPromise
  • Tagged errors (_tag)
  • catchTag/catchTags

We will explore more error handling solutions and APIs later, as well as easier and more powerful ways to define tagged errors.

Effect enables you to do a lot more than returning an error message:

  • Retry requests on a custom schedule
  • Try a different request if the first fails
  • Recover from errors with another valid value

Wait for it, things are gonna get more and more powerful!

But now let's come back to our goal: make an API request.