Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -21505,9 +21505,9 @@ static bool js_async_function_resume(JSContext *ctx, JSAsyncFunctionData *s)
bool is_success = true;
JSValue func_ret, ret2;

resume:
func_ret = async_func_resume(ctx, &s->func_state);
if (JS_IsException(func_ret)) {
fail:
if (unlikely(JS_IsUncatchableError(ctx->rt->current_exception))) {
is_success = false;
} else {
Expand Down Expand Up @@ -21546,10 +21546,10 @@ static bool js_async_function_resume(JSContext *ctx, JSAsyncFunctionData *s)
1, vc(&value), 0);
JS_FreeValue(ctx, value);
if (JS_IsException(promise))
goto fail;
goto await_fail;
if (js_async_function_resolve_create(ctx, s, resolving_funcs)) {
JS_FreeValue(ctx, promise);
goto fail;
goto await_fail;
}

/* Note: no need to create 'thrownawayCapability' as in
Expand All @@ -21562,8 +21562,11 @@ static bool js_async_function_resume(JSContext *ctx, JSAsyncFunctionData *s)
JS_FreeValue(ctx, promise);
for(i = 0; i < 2; i++)
JS_FreeValue(ctx, resolving_funcs[i]);
if (res)
goto fail;
if (res) {
await_fail:
s->func_state.throw_flag = true;
goto resume;
}
}
}
return is_success;
Expand Down
69 changes: 69 additions & 0 deletions tests/bug1757.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// https://github.com/quickjs-ng/quickjs/issues/1757
import { assert } from "./assert.js";

const error = new Error("boom");
const promise = Promise.resolve(1);
let calls = 0;
Object.defineProperty(promise, "constructor", {
get() {
calls++;
throw error;
},
});

const log = [];
const result = (async () => {
for (let i = 0; i < 2; i++) {
try {
await promise;
assert(false);
} catch (e) {
assert(e === error);
log.push("catch");
} finally {
log.push("finally");
}
}
assert(await Promise.resolve(42), 42);
try {
await promise;
assert(false);
} catch (e) {
assert(e === error);
log.push("resumed catch");
}
return 123;
})();

// PromiseResolve throws before Await suspends the execution context.
assert(log.join(","), "catch,finally,catch,finally");
assert(await result, 123);
assert(log.join(","), "catch,finally,catch,finally,resumed catch");
assert(calls, 3);

let finalized = false;
const rejected = (async () => {
try {
await promise;
} finally {
await 0;
finalized = true;
}
})();
let caught = false;
try {
await rejected;
} catch (e) {
assert(e === error);
caught = true;
}
assert(caught);
assert(finalized);

assert(await (async () => {
try {
return await promise;
} finally {
return 456;
}
})(), 456);
Loading