When different status codes require different handling, use HttpClientResponse.matchStatus(). It lets you branch your logic based on exact status codes or status code ranges.
import { FetchHttpClient, HttpClient, HttpClientRequest, HttpClientResponse,} from "effect/unstable/http";import { Effect } from "effect";
function fetchUser(userId: number) { return Effect.gen(function* () { const client = yield* HttpClient.HttpClient;
const request = HttpClientRequest.get( `https://dummyjson.com/users/${userId}`, );
const response = yield* client.execute(request);
return HttpClientResponse.matchStatus(response, { // Exact status code 200: (response) => Effect.gen(function* () { const user = yield* response.json; return `Found user: ${user.firstName} ${user.lastName}`; }), 404: () => Effect.succeed("User not found"), // Range matchers for status code classes "4xx": (response) => Effect.succeed(`Client error: ${response.status}`), "5xx": (response) => Effect.succeed(`Server error: ${response.status}`), // Catch-all for any other status orElse: (response) => Effect.succeed(`Unexpected status: ${response.status}`), }); }).pipe(Effect.flatten, Effect.provide(FetchHttpClient.layer));}
// Test with different user IDsEffect.runPromise(fetchUser(1)).then(console.log);Effect.runPromise(fetchUser(9999)).then(console.log);Output:
User not foundFound user: Emily JohnsonIn the example above, we use Effect.flatten because matchStatus is a plain function that returns whatever each branch returns, and our branches return Effects. These returned Effects sit inside the outer Effect.gen, which wraps them in another Effect layer, giving us Effect<Effect<string>>. Effect.flatten unwraps one layer to give us the Effect<string> we need.
matchStatus checks cases in this order: exact status codes first (like 200, 404), then range matchers (“2xx”, “3xx”, “4xx”, “5xx”), and finally orElse as the fallback.
The orElse case is required. This ensures you always handle every possible status code, even unexpected ones.
Exact codes take priority over ranges. In the example above, a 404 response hits the 404 case, not the “4xx” case.