Skip to content

Fix exception propagation when preparing await - #1793

Open
xeioex wants to merge 1 commit into
quickjs-ng:masterfrom
xeioex:master
Open

xeioex wants to merge 1 commit into
quickjs-ng:masterfrom
xeioex:master

Conversation

@xeioex

@xeioex xeioex commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Fixes #1757.

Errors while preparing await currently reject the async function's outer promise directly, skipping its catch and finally blocks. Resume the function with the pending exception instead, including errors from callback creation and promise reaction allocation.

The specification requires Await to propagate an abrupt completion from PromiseResolve, including a throwing promise.constructor getter:

For example:

const p = Promise.resolve(1);
Object.defineProperty(p, "constructor", {
    get() { throw new Error("boom"); }
});

(async () => {
    try {
        await p;
    } catch (e) {
        console.log(e.message);
    } finally {
        console.log("cleanup");
    }
})();

Expected output: boom, then cleanup. Both blocks are skipped before the fix.

A finally block can also override the exception:

(async () => {
    try {
        await p;
    } finally {
        return 42;
    }
})().then(console.log); // 42

Validation:

  • Regression test passes in QuickJS and Node.js 25.2.1.
  • Fault injection confirms catch/finally run after allocation failures.
  • Project tests and focused async test262 pass under clang-18 ASan/UBSan.
  • Full Release test262: 82,220 checks, no new failures against the baseline.

Resume the suspended async function with throw_flag when PromiseResolve,
callback creation, or promise reaction allocation fails. Rejecting its
outer promise directly skips catch and finally blocks around await.

Add a regression test for exception identity, synchronous catch/finally
execution, repeated failures, and recovery after a successful await.

Fixes quickjs-ng#1757

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

await bypasses catch when PromiseResolve throws

1 participant