HttpClient.catchTag() catches only errors with a specific _tag, letting other error types pass through.
This is useful when your client’s error channel contains multiple error types. For example, if you use schema validation on responses, the error channel includes both HttpClientError (from the HTTP request) and SchemaError (from validation). catchTag lets you recover from one while letting the other propagate.
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, // Only catch HttpClientError (network failures, bad status codes, etc.) // SchemaError from validation is NOT caught — it will still propagate HttpClient.catchTag("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);
// This can fail with SchemaError, which is NOT caught by catchTag above const user = yield* HttpClientResponse.schemaBodyJson(User)(response);
return user; }).pipe(Effect.provide(FetchHttpClient.layer));}
// Test with an invalid user — HttpClientError is caught, fallback is usedEffect.runPromise(fetchUser(9999)).then( (user) => console.log("User:", user.firstName, user.lastName), (error) => console.error(`[${error._tag}] ${error.message}`),);Output:
HTTP error: StatusCode: non 2xx status code (404 GET https://dummyjson.com/users/9999)Falling back to default user...User: Emily JohnsonThe power of catchTag shows when other error types are in the channel. In this example, a SchemaError from schemaBodyJson would bypass the catchTag handler entirely and propagate to the caller. This lets you be precise: recover from HTTP failures (server down, bad status code) while still surfacing data integrity issues (unexpected response shape) as errors that need attention.
If your client only produces HttpClientError and you want to catch everything, HttpClient.catch is simpler. Reach for catchTag when multiple error types are in play and you need selective recovery.