denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
93.4k stars 5.18k forks source link

Async function that named `using` does not work properly from Deno v1.36.2 #20271

Closed lambdalisue closed 7 months ago

lambdalisue commented 10 months ago

It is difficult to explain the phenomenon, but at any rate, after this commit, using a function named using behaves strangely. Specifically, assertRejects cannot catch errors thrown without the internal async function, or it cannot wait for the internal async function to complete (I have tried everything, but the behavior does not seem consistent).

image

The contents of the using function are not related to the phenomenon (because the behavior is fixed if I renamed using to usingA or whatever), but they are as follows.

export async function using<T extends Disposable, R = unknown>(
  resource: T,
  fn: (resource: T) => R | Promise<R>,
): Promise<R> {
  try {
    return await fn(resource);
  } finally {
    await resource.dispose();
  }
}

If this function is used in the form of "await using" as shown below, the behavior will suddenly become strange.

Deno.test("using ensure asynchronous disposable is disposed even on error", async () => {
  const calls = [];

  calls.push("enter");
  await assertRejects(async () => {
    await using(
      new AsynchronousDisposable(() => calls.push("dispose")),
      (r) => {
        assert(r instanceof AsynchronousDisposable);
        calls.push("fn");
        throw new Error("Error");
      },
    );
  });
  calls.push("leave");

  assertEquals(calls, [
    "enter",
    "fn",
    "dispose",
    "leave",
  ]);
});

You can find all codes in the following library (it's small enough to check I think)

https://github.com/lambdalisue/deno-disposable

I'm thinking that perhaps the await using part of the behavior has changed since TypeScirpt 5.2 due to the increase in the using keyword, but I honestly don't know.

lucacasonato commented 8 months ago

Sorry about that! It's a regression from the introduction of using declarations.

Upstream parser bug: https://github.com/swc-project/swc/issues/8096

dsherret commented 7 months ago

Seems fixed for a while now.