Skip to content

Commit

Permalink
adapt changes from nodejs#34862
Browse files Browse the repository at this point in the history
  • Loading branch information
Uzlopak committed Mar 17, 2024
1 parent f362a6a commit 13e0e13
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 13 deletions.
31 changes: 18 additions & 13 deletions lib/internal/process/promises.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const {
ArrayPrototypeShift,
Error,
ObjectPrototypeHasOwnProperty,
SafeMap,
SafeWeakMap,
} = primordials;

Expand Down Expand Up @@ -149,9 +150,10 @@ class PromiseRejectionHandledWarning extends Error {
const maybeUnhandledPromises = new SafeWeakMap();

/**
* @type {Promise[]}
* Using a Mp causes the promise to be referenced at least for one tick.
* @type {Map<Promise, PromiseInfo>}
*/
const pendingUnhandledRejections = [];
let pendingUnhandledRejections = new SafeMap();

/**
* @type {Array<{promise: Promise, warning: Error}>}
Expand Down Expand Up @@ -279,21 +281,23 @@ const emitUnhandledRejection = (promise, promiseInfo) => {
* @param {Error} reason
*/
function unhandledRejection(promise, reason) {
maybeUnhandledPromises.set(promise, {
pendingUnhandledRejections.set(promise, {
reason,
uid: ++lastPromiseId,
warned: false,
domain: process.domain,
});
// This causes the promise to be referenced at least for one tick.
ArrayPrototypePush(pendingUnhandledRejections, promise);
setHasRejectionToWarn(true);
}

/**
* @param {Promise} promise
*/
function handledRejection(promise) {
if (pendingUnhandledRejections.has(promise)) {
pendingUnhandledRejections.delete(promise);
return;
}
const promiseInfo = maybeUnhandledPromises.get(promise);
if (promiseInfo !== undefined) {
maybeUnhandledPromises.delete(promise);
Expand Down Expand Up @@ -465,16 +469,17 @@ function processPromiseRejections() {
}
}

let len = pendingUnhandledRejections.length;
let needPop = true;
let promiseAsyncId;

while (len--) {
const promise = ArrayPrototypeShift(pendingUnhandledRejections);
const promiseInfo = maybeUnhandledPromises.get(promise);
if (promiseInfo === undefined) {
continue;
}
const pending = pendingUnhandledRejections;
pendingUnhandledRejections = new SafeMap();

for (const { 0: promise, 1: promiseInfo } of pending.entries()) {
pending.delete(promise);

maybeUnhandledPromises.set(promise, promiseInfo);

promiseInfo.warned = true;

// We need to check if async_hooks are enabled
Expand All @@ -499,7 +504,7 @@ function processPromiseRejections() {
maybeScheduledTicksOrMicrotasks = true;
}
return maybeScheduledTicksOrMicrotasks ||
pendingUnhandledRejections.length !== 0;
pendingUnhandledRejections.size !== 0;
}

function listenForRejections() {
Expand Down
26 changes: 26 additions & 0 deletions test/parallel/test-promise-unhandled-issue-43655.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

require('../common');
const assert = require('assert');

function delay(time) {
return new Promise((resolve) => {
setTimeout(resolve, time);
});
}

async function test() {
for (let i = 0; i < 1000000; i++) {
await new Promise((resolve, reject) => {
reject('value');
})
.then(() => { }, () => { });
}

const time0 = Date.now();
await delay(0);

assert.ok(Date.now() - time0 < 10);
}

test();

0 comments on commit 13e0e13

Please sign in to comment.