v8/test/mjsunit/harmony/promise-all-settled.js
Camillo Bruni 1335b1ec36 [d8] Exit with error code upon unhandled promise rejection
With this CL d8 exits with an error code if there is an unhandled
promise rejection, e.g. due tue a failed assertion in a promise. Up
until now these assertions were just ignored.

Bug: v8:10556
Change-Id: I25f20e4be45a2de130562deb15f6a144f0ac976f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2238569
Reviewed-by: Yang Guo <yangguo@chromium.org>
Reviewed-by: Marja Hölttä <marja@chromium.org>
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68503}
2020-06-24 07:21:58 +00:00

260 lines
5.6 KiB
JavaScript

// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --harmony-promise-all-settled --ignore-unhandled-promises
class MyError extends Error {}
const descriptor = Object.getOwnPropertyDescriptor(Promise, "allSettled");
assertTrue(descriptor.configurable);
assertTrue(descriptor.writable);
assertFalse(descriptor.enumerable);
// 1. Let C be the this value.
// 2. If Type(C) is not Object, throw a TypeError exception.
assertThrows(() => Promise.allSettled.call(1), TypeError);
{
// 3. Let promiseCapability be ? NewPromiseCapability(C).
let called = false;
class MyPromise extends Promise {
constructor(...args) {
called = true;
super(...args);
}
}
MyPromise.allSettled([]);
assertTrue(called);
}
{
// 4. Let iteratorRecord be GetIterator(iterable).
// 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
let caught = false;
(async function() {
class MyError extends Error {}
let err;
try {
await Promise.allSettled({
[Symbol.iterator]() {
throw new MyError();
}
});
} catch (e) {
assertTrue(e instanceof MyError);
caught = true;
}
})();
%PerformMicrotaskCheckpoint();
assertTrue(caught);
}
{
// 6. a. Let next be IteratorStep(iteratorRecord).
let iteratorStep = false;
(async function() {
try {
await Promise.allSettled({
[Symbol.iterator]() {
return {
next() {
iteratorStep = true;
return { done: true }
}
};
}
});
} catch (e) {
%AbortJS(e.stack);
}
})();
%PerformMicrotaskCheckpoint();
assertTrue(iteratorStep);
}
{
// 6. a. Let next be IteratorStep(iteratorRecord).
// 6. b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
// 6. c. ReturnIfAbrupt(next).
let caught = false;
(async function() {
try {
await Promise.allSettled({
[Symbol.iterator]() {
return {
next() {
throw new MyError();
}
};
}
});
} catch (e) {
assertTrue(e instanceof MyError);
caught = true;
}
})();
%PerformMicrotaskCheckpoint();
assertTrue(caught);
}
{
// 6. e. Let nextValue be IteratorValue(next).
let iteratorValue = false;
(async function() {
try {
await Promise.allSettled({
[Symbol.iterator]() {
let done = false;
return {
next() {
let result = { value: 1, done };
iteratorValue = true;
done = true;
return result;
}
};
}
});
} catch (e) {
%AbortJS(e.stack);
}
})();
%PerformMicrotaskCheckpoint();
assertTrue(iteratorValue);
}
{
// 6. e. Let nextValue be IteratorValue(next).
// 6. f. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
// 6. g. ReturnIfAbrupt(nextValue).
let caught = false;
(async function() {
try {
await Promise.allSettled({
[Symbol.iterator]() {
let done = false;
return {
next() {
return result = {
get value() {throw new MyError(''); },
done: false
};
}
};
}
});
} catch (e) {
assertTrue(e instanceof MyError);
caught = true;
}
})();
%PerformMicrotaskCheckpoint();
assertTrue(caught);
}
{
// TODO(mathias): https://github.com/tc39/proposal-promise-allSettled/pull/40
// 6. i. Let nextPromise be ? Invoke(constructor, "resolve", « nextValue »).
let called = false;
class MyPromise extends Promise {
static resolve(...args) {
called = true;
super.resolve(...args);
}
}
MyPromise.allSettled([1]);
assertTrue(called);
}
{
// 6. z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
let called = false;
class MyPromise extends Promise {
then(...args) {
called = true;
super.resolve(...args);
}
}
MyPromise.allSettled([1]);
assertTrue(called);
}
{
let called = false;
let result;
Promise.allSettled([]).then(x => {
called = true;
result = x;
});
%PerformMicrotaskCheckpoint();
assertTrue(called);
assertEquals(result, []);
}
{
let called = false;
Promise.allSettled([Promise.resolve("foo")]).then(v => {
assertEquals(v.length, 1);
const [x] = v;
assertSame(Object.getPrototypeOf(x), Object.getPrototypeOf({}));
const descs = Object.getOwnPropertyDescriptors(x);
assertEquals(Object.keys(descs).length, 2);
const { value: desc } = descs;
assertTrue(desc.writable);
assertTrue(desc.enumerable);
assertTrue(desc.configurable);
assertEquals(x.value, "foo");
assertEquals(x.status, "fulfilled");
called = true;
});
%PerformMicrotaskCheckpoint();
assertTrue(called);
}
{
let called = false;
Promise.allSettled([Promise.reject("foo")]).then(v => {
assertEquals(v.length, 1);
const [x] = v;
assertEquals(x.reason, "foo");
assertEquals(x.status, "rejected");
called = true;
});
%PerformMicrotaskCheckpoint();
assertTrue(called);
}
{
let called = false;
Promise.allSettled([Promise.resolve("bar"), Promise.reject("foo")]).then(v => {
assertEquals(v.length, 2);
const [x, y] = v;
assertEquals(x.value, "bar");
assertEquals(x.status, "fulfilled");
assertEquals(y.reason, "foo");
assertEquals(y.status, "rejected");
called = true;
});
%PerformMicrotaskCheckpoint();
assertTrue(called);
}