From 0965ce1df932f018882ecdbafdd5af3e307a68e0 Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Mon, 21 Sep 2026 21:56:00 -0700 Subject: [PATCH] Promise: reject empty any inputs Reject Promise.any() with an AggregateError when the input contains no promises, as required by the promise combinator semantics. --- src/njs_promise.c | 5 ++++- test/js/promise_any.t.js | 14 ++++++++++---- test/njs_test262.failures | 5 ----- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/njs_promise.c b/src/njs_promise.c index 016c6859..fadde167 100644 --- a/src/njs_promise.c +++ b/src/njs_promise.c @@ -1291,7 +1291,10 @@ njs_promise_perform_all(njs_vm_t *vm, njs_value_t *iterator, njs_error_stack_attach(vm, argument, 1); } - ret = njs_function_call(vm, njs_function(&pargs->capability->resolve), + ret = njs_function_call(vm, njs_function(handler + == njs_promise_perform_any_handler + ? &pargs->capability->reject + : &pargs->capability->resolve), &njs_value_undefined, &argument, 1, retval); if (njs_slow_path(ret == NJS_ERROR)) { return ret; diff --git a/test/js/promise_any.t.js b/test/js/promise_any.t.js index fb287ba9..d97e8484 100644 --- a/test/js/promise_any.t.js +++ b/test/js/promise_any.t.js @@ -7,8 +7,14 @@ var p0 = Promise.resolve().then(() => { throw 'foo' }); var p1 = Promise.reject(2).catch(v => v * 2); var p2 = Promise.resolve(1).then(v => v + 1); -Promise.any([p0, p1, p2]).then( - v => assert.sameValue(v, 4), - v => $DONOTEVALUATE(), -) +Promise.any([]).then( + () => $DONOTEVALUATE(), + e => { + assert.sameValue(e.constructor, AggregateError); + assert.sameValue(e.errors.length, 0); + }, +).then(() => Promise.any([p0, p1, p2]).then( + v => assert.sameValue(v, 4), + v => $DONOTEVALUATE(), + )) .then($DONE, $DONE); diff --git a/test/njs_test262.failures b/test/njs_test262.failures index 2e308663..4d261624 100644 --- a/test/njs_test262.failures +++ b/test/njs_test262.failures @@ -456,8 +456,6 @@ built-ins/Promise/allSettled/resolve-non-callable.js strict built-ins/Promise/allSettled/resolve-not-callable-reject-with-typeerror.js strict built-ins/Promise/allSettled/resolve-throws-iterator-return-is-not-callable.js strict built-ins/Promise/allSettled/resolve-throws-iterator-return-null-or-undefined.js strict -built-ins/Promise/any/call-reject-element-after-return.js strict -built-ins/Promise/any/call-reject-element-items.js strict built-ins/Promise/any/capability-reject-throws-no-close.js strict built-ins/Promise/any/capability-resolve-throws-no-close.js strict built-ins/Promise/any/capability-resolve-throws-reject.js strict @@ -471,8 +469,6 @@ built-ins/Promise/any/invoke-resolve.js strict built-ins/Promise/any/invoke-then-error-reject.js strict built-ins/Promise/any/invoke-then-get-error-reject.js strict built-ins/Promise/any/invoke-then-on-promises-every-iteration.js strict -built-ins/Promise/any/iter-arg-is-empty-iterable-reject.js strict -built-ins/Promise/any/iter-arg-is-empty-string-reject.js strict built-ins/Promise/any/iter-arg-is-error-object-reject.js strict built-ins/Promise/any/iter-arg-is-false-reject.js strict built-ins/Promise/any/iter-arg-is-null-reject.js strict @@ -490,7 +486,6 @@ built-ins/Promise/any/iter-returns-string-reject.js strict built-ins/Promise/any/iter-returns-symbol-reject.js strict built-ins/Promise/any/iter-returns-true-reject.js strict built-ins/Promise/any/iter-returns-undefined-reject.js strict -built-ins/Promise/any/resolve-before-loop-exit.js strict built-ins/Promise/any/resolve-non-callable.js strict built-ins/Promise/any/resolve-not-callable-reject-with-typeerror.js strict built-ins/Promise/any/resolve-throws-iterator-return-is-not-callable.js strict -- 2.47.3