Effect provides a composable service to handle configuration values: Config.
Config is responsible to extract configuration values and provide them in our code. In our example we create a Config for the PokéApi base url using Config.string.
Config.string accepts a string parameter that specifies the key of the configuration value to extract ("BASE_URL"):
import { Config } from "effect";
const config = Config.string("BASE_URL");Config can then be used just like a normal Effect inside .gen. We first update fetchRequest to accept a baseUrl parameter:
const fetchRequest = (baseUrl: string) =>
  Effect.tryPromise({
    try: () => fetch(`${baseUrl}/api/v2/pokemon/garchomp/`),
    catch: () => new FetchError(),
  });We then provide it from config:
const config = Config.string("BASE_URL");
const program = Effect.gen(function* () {
  const baseUrl = yield* config;
  const response = yield* fetchRequest(baseUrl);
  if (!response.ok) {
    return yield* new FetchError();
  }
  const json = yield* jsonResponse(response);
  return yield* decodePokemon(json);
});Since extracting configuration is an effectful operation that may fail, using
Configrequiresyield*.It also adds a
ConfigErrorto the union of errors of theprogramtype.
programnow is of typeEffect<Pokemon, FetchError | JsonError | ParseError | ConfigError>.See how handy is to have all the errors in the type signature? 🚀
Since a missing configuration value is an implementation error, it's common to not handle
ConfigError(not usecatchTagon it).Instead it's usually better to let the app fail, since we cannot recover anyway from these kind of errors (you should fix your configuration!).
