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
16 changes: 8 additions & 8 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -32138,21 +32138,21 @@ static JSValue js_async_module_execution_rejected(JSContext *ctx, JSValueConst t
module->eval_exception = js_dup(error);
module->status = JS_MODULE_STATUS_EVALUATED;

for(i = 0; i < module->async_parent_modules_count; i++) {
JSModuleDef *m = module->async_parent_modules[i];
JSValue m_obj = JS_NewModuleValue(ctx, m);
js_async_module_execution_rejected(ctx, JS_UNDEFINED, 1, &error, 0,
vc(&m_obj));
JS_FreeValue(ctx, m_obj);
}

if (!JS_IsUndefined(module->promise)) {
JSValue ret_val;
assert(module->cycle_root == module);
ret_val = JS_Call(ctx, module->resolving_funcs[1], JS_UNDEFINED,
1, &error);
JS_FreeValue(ctx, ret_val);
}

for(i = 0; i < module->async_parent_modules_count; i++) {
JSModuleDef *m = module->async_parent_modules[i];
JSValue m_obj = JS_NewModuleValue(ctx, m);
js_async_module_execution_rejected(ctx, JS_UNDEFINED, 1, &error, 0,
vc(&m_obj));
JS_FreeValue(ctx, m_obj);
}
return JS_UNDEFINED;
}

Expand Down
1 change: 0 additions & 1 deletion test262_errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ test262/test/language/module-code/ambiguous-export-bindings/namespace-unambiguou
test262/test/language/module-code/ambiguous-export-bindings/namespace-unambiguous-if-export-star-as-from.js:75: SyntaxError: export 'foo' in module 'test262/test/language/module-code/ambiguous-export-bindings/nam' is ambiguous
test262/test/language/module-code/ambiguous-export-bindings/namespace-unambiguous-if-import-star-as-and-export.js:74: SyntaxError: export 'foo' in module 'test262/test/language/module-code/ambiguous-export-bindings/nam' is ambiguous
test262/test/language/module-code/top-level-await/module-graphs-does-not-hang.js:10: TypeError: $DONE() not called
test262/test/language/module-code/top-level-await/rejection-order.js:20: TypeError: $DONE() not called
test262/test/language/statements/await-using/initializer-Symbol.asyncDispose-disposed-at-end-of-imported-module.js:11: SyntaxError: exported variable 'resource' does not exist
test262/test/language/statements/await-using/initializer-Symbol.dispose-disposed-at-end-of-imported-module.js:11: SyntaxError: exported variable 'resource' does not exist
test262/test/language/statements/class/elements/syntax/valid/grammar-field-named-get-followed-by-generator-asi.js:40: SyntaxError: invalid property name
Expand Down
6 changes: 6 additions & 0 deletions tests.conf
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,9 @@ tests/fixture_throwing_module.js
tests/fixture_reexport_source.js
tests/fixture_reexport_missing.js
tests/fixture_reexport_direct.js
tests/fixture_reject_leaf.js
tests/fixture_reject_mid.js
tests/fixture_reject_top.js
tests/fixture_reject_sib_leaf.js
tests/fixture_reject_sib_a.js
tests/fixture_reject_sib_b.js
3 changes: 3 additions & 0 deletions tests/fixture_reject_leaf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* the async module that actually fails */
await Promise.resolve();
throw new Error("leaf rejected");
2 changes: 2 additions & 0 deletions tests/fixture_reject_mid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import "./fixture_reject_leaf.js";
export const mid = 1;
2 changes: 2 additions & 0 deletions tests/fixture_reject_sib_a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import "./fixture_reject_sib_leaf.js";
export const a = 1;
2 changes: 2 additions & 0 deletions tests/fixture_reject_sib_b.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import "./fixture_reject_sib_leaf.js";
export const b = 1;
2 changes: 2 additions & 0 deletions tests/fixture_reject_sib_leaf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
await Promise.resolve();
throw new Error("sibling leaf rejected");
2 changes: 2 additions & 0 deletions tests/fixture_reject_top.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import "./fixture_reject_mid.js";
export const top = 1;
61 changes: 61 additions & 0 deletions tests/module-async-rejection-order.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { assert } from "./assert.js";

/* AsyncModuleExecutionRejected rejects the module's own [[TopLevelCapability]]
before recursing into [[AsyncParentModules]], so a failing async module
settles leaf first and root last. Doing it the other way around settles the
whole chain in reverse. */

/* Importing the leaf first, then each ancestor in turn, gives every module in
the chain its own top level capability, which is what makes the order
observable at all. */
const order = [];
const errors = [];

function record(name) {
return e => { order.push(name); errors.push(e); };
}

const leaf = import("./fixture_reject_leaf.js").then(record("leaf.ok"),
record("leaf"));
const mid = import("./fixture_reject_mid.js").then(record("mid.ok"),
record("mid"));
const top = import("./fixture_reject_top.js").then(record("top.ok"),
record("top"));

await Promise.all([leaf, mid, top]);

assert(order.join(" -> "), "leaf -> mid -> top");

/* every module in the chain reports the leaf's error, and it is the very
same object, not a copy */
assert(errors.length, 3);
for (const e of errors) {
assert(e instanceof Error, true);
assert(e.message, "leaf rejected");
assert(e === errors[0], true);
}

/* re-importing the failed modules keeps reporting the same error and does
not re-run anything */
{
const again = [];
await Promise.all([
import("./fixture_reject_leaf.js").then(() => again.push("ok"),
e => again.push(e.message)),
import("./fixture_reject_top.js").then(() => again.push("ok"),
e => again.push(e.message)),
]);
assert(again.length, 2);
assert(again[0], "leaf rejected");
assert(again[1], "leaf rejected");
}

/* two independent ancestors of the same failing leaf are both notified */
{
const seen = [];
const a = import("./fixture_reject_sib_a.js").catch(e => seen.push("a"));
const b = import("./fixture_reject_sib_b.js").catch(e => seen.push("b"));
await Promise.all([a, b]);
seen.sort();
assert(seen.join(","), "a,b");
}
Loading