Skip to content

Commit 59a8425

Browse files
lundibunditargos
authored andcommittedApr 30, 2021
timers: fix multipleResolves in promisified timeouts/immediates
After successful timer finish the abort event callback would still reject (already resolved promise) upon calling abortController.abort(). Signed-off-by: Denys Otrishko <[email protected]> PR-URL: #33949 Backport-PR-URL: #38386 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent 84b2863 commit 59a8425

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed
 

‎lib/timers.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,10 @@ setTimeout[customPromisify] = function(after, value, options = {}) {
201201
insert(timeout, timeout._idleTimeout);
202202
if (signal) {
203203
signal.addEventListener('abort', () => {
204-
clearTimeout(timeout);
205-
reject(lazyDOMException('AbortError'));
204+
if (!timeout._destroyed) {
205+
clearTimeout(timeout);
206+
reject(lazyDOMException('AbortError'));
207+
}
206208
}, { once: true });
207209
}
208210
});
@@ -368,8 +370,10 @@ setImmediate[customPromisify] = function(value, options = {}) {
368370
const immediate = new Immediate(resolve, [value]);
369371
if (signal) {
370372
signal.addEventListener('abort', () => {
371-
clearImmediate(immediate);
372-
reject(lazyDOMException('AbortError'));
373+
if (!immediate._destroyed) {
374+
clearImmediate(immediate);
375+
reject(lazyDOMException('AbortError'));
376+
}
373377
}, { once: true });
374378
}
375379
});

‎test/parallel/test-timers-promisified.js

+19
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ const { promisify } = require('util');
1010
const setTimeout = promisify(timers.setTimeout);
1111
const setImmediate = promisify(timers.setImmediate);
1212

13+
process.on('multipleResolves', common.mustNotCall());
14+
1315
{
1416
const promise = setTimeout(1);
1517
promise.then(common.mustCall((value) => {
@@ -66,6 +68,23 @@ const setImmediate = promisify(timers.setImmediate);
6668
assert.rejects(setImmediate(10, { signal }), /AbortError/);
6769
}
6870

71+
{
72+
// Check that aborting after resolve will not reject.
73+
const ac = new AbortController();
74+
const signal = ac.signal;
75+
setTimeout(10, undefined, { signal }).then(() => {
76+
ac.abort();
77+
});
78+
}
79+
{
80+
// Check that aborting after resolve will not reject.
81+
const ac = new AbortController();
82+
const signal = ac.signal;
83+
setImmediate(10, { signal }).then(() => {
84+
ac.abort();
85+
});
86+
}
87+
6988
{
7089
Promise.all(
7190
[1, '', false, Infinity].map((i) => assert.rejects(setImmediate(10, i)), {

0 commit comments

Comments
 (0)
Please sign in to comment.