Lesson 02 of 6 in Effect, one function at a time

Wrap a promise with Effect.tryPromise

Turn a promise that can fail into an Effect.

Many libraries hand you a promise. Effect.tryPromise turns that promise into an Effect, and you decide how a rejection should be shaped.

import { Effect } from "effect";

type FetchError = { readonly _tag: "FetchFailed"; readonly reason: string };

export const fetchText = (url: string) =>
	Effect.tryPromise({
		try: async () => {
			const res = await fetch(url);
			if (!res.ok) throw new Error(`HTTP ${res.status}`);
			return res.text();
		},
		catch: (cause): FetchError => ({
			_tag: "FetchFailed",
			reason: String(cause),
		}),
	});

Two things to notice:

Without the catch mapping, the failure would be an unknown value, and every caller would have to guess what it is. Give the failure a tag from the start.

The promise is only started when the Effect runs, so building the value does not fetch anything.