Title: Handling Asynchronous Validation in Effect Typescript Schema

I have a schema that needs to fetch external data when in validation. This data is being parsed by the HttpClientResponse.schemaBodyJson method and I'm getting an error of: AsyncFiberException: Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work

Here's what the async schema code looks like:
type BaseProduct = Schema.Schema.Type<typeof BaseProduct>;
const BaseProduct = Schema.Struct({
  id: Resource.ID,
  title: Schema.String,
  handle: Schema.String,
  variants: Schema.Array(BaseVariant),
  options: Schema.Array(ProductOption),
  tags: Schema.Array(Schema.String),
});

const get = (url: string): Effect.Effect<unknown, Error> =>
  Effect.tryPromise({
    try: () =>
      fetch(url).then((res) => {
        if (res.ok) {
          return res.json() as Promise<unknown>;
        }
        throw new Error(String(res.status));
      }),
    catch: (e) => new Error(String(e)),
  });

const cachedGet = (url: string) =>
  Effect.gen(function* () {
    const cache = yield* Effect.cachedWithTTL(get(url), "60 minutes");
    return yield* cache;
  });

const Product = Schema.transformOrFail(Schema.String, BaseProduct, {
  decode(handle, _, ast) {
    return Effect.mapBoth(cachedGet(`/products/${handle}`), {
      onFailure: (e) => new ParseResult.Type(ast, handle, e.message),
      onSuccess: (product) => product as BaseProduct,
    });
  },
  encode: (product) => ParseResult.succeed(product.handle),
});


Here's what the code that runs the HttpClientResponse.schemaBodyJson looks like:
      const json = yield* Function.pipe(
        response,
        HttpClientResponse.schemaBodyJson(output),
      );


Here's the final output of the program:
      Effect.runPromise(
        API.add(input).pipe(
          Logger.withMinimumLogLevel(minimumLogLevel),
          Effect.provide(ajaxLayer)))


Is there something I'm doing wrong? Do I need to handle the decode process differently?
Was this page helpful?