Catching Multiple Error Types

Avatar of Hemanta SundarayHemanta Sundaray

HttpClient.catchTags() handles multiple error types in a single call, with a separate handler for each _tag.

This is the cleanest option when your client’s error channel contains several error types and you want distinct recovery strategies for each.

http.ts
import {
FetchHttpClient,
HttpClient,
HttpClientRequest,
HttpClientResponse,
} from "effect/unstable/http";
import { Effect, Schema } from "effect";
const User = Schema.Struct({
id: Schema.Number,
firstName: Schema.String,
lastName: Schema.String,
});
function fetchUser(userId: number) {
return Effect.gen(function* () {
const client = (yield* HttpClient.HttpClient).pipe(
HttpClient.filterStatusOk,
HttpClient.catchTags({
HttpClientError: (error) =>
Effect.gen(function* () {
console.log(`HTTP error: ${error.message}`);
console.log("Falling back to default user...");
const fallbackClient = yield* HttpClient.HttpClient;
return yield* fallbackClient.get("https://dummyjson.com/users/1");
}),
}),
);
const request = HttpClientRequest.get(
`https://dummyjson.com/users/${userId}`,
);
const response = yield* client.execute(request);
const user = yield* HttpClientResponse.schemaBodyJson(User)(response);
return user;
}).pipe(Effect.provide(FetchHttpClient.layer));
}
// Test with an invalid user — HttpClientError is caught, fallback is used
Effect.runPromise(fetchUser(9999)).then(
(user) => console.log("User:", user.firstName, user.lastName),
(error) => console.error(`[${error._tag}] ${error.message}`),
);

Output:

Terminal
HTTP error: StatusCode: non 2xx status code (404 GET https://dummyjson.com/users/9999)
Falling back to default user...
User: Emily Johnson

catchTags takes an object where each key is a _tag value and each value is a handler function. You don’t need to handle every possible tag, only the ones you list. Unhandled tags remain in the error channel.

In this example, HttpClientError is caught and recovered with a fallback request. But SchemaError (from schemaBodyJson) is not listed, so it would propagate to the caller if the response shape doesn’t match the schema.

catchTags shines when you have three or more error types in the channel and want to handle each one differently in a single, readable block. If you only need to catch one specific tag, catchTag is simpler. If you want to catch everything, use catch.

Sign in to save progress

Stay in the loop

Get notified when new chapters are added and when this course is complete.