Skip to content

Commit d784dbf

Browse files
apapirovskijasnell
authored andcommitted
timers: call destroy on interval error
When an interval callback throws an error, the destroy hook is never called due to a faulty if condition. PR-URL: #20001 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]>
1 parent f395c21 commit d784dbf

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

lib/timers.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ function tryOnTimeout(timer, start) {
292292
if (timerAsyncId !== null) {
293293
if (!threw)
294294
emitAfter(timerAsyncId);
295-
if (!timer._repeat && destroyHooksExist() &&
295+
if ((threw || !timer._repeat) && destroyHooksExist() &&
296296
!timer._destroyed) {
297297
emitDestroy(timerAsyncId);
298298
timer._destroyed = true;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const initHooks = require('./init-hooks');
6+
const { checkInvocations } = require('./hook-checks');
7+
const TIMEOUT = common.platformTimeout(100);
8+
9+
const hooks = initHooks();
10+
hooks.enable();
11+
12+
setInterval(common.mustCall(ontimeout), TIMEOUT);
13+
const as = hooks.activitiesOfTypes('Timeout');
14+
assert.strictEqual(as.length, 1);
15+
const t1 = as[0];
16+
assert.strictEqual(t1.type, 'Timeout');
17+
assert.strictEqual(typeof t1.uid, 'number');
18+
assert.strictEqual(typeof t1.triggerAsyncId, 'number');
19+
checkInvocations(t1, { init: 1 }, 't1: when timer installed');
20+
21+
function ontimeout() {
22+
checkInvocations(t1, { init: 1, before: 1 }, 't1: when first timer fired');
23+
24+
throw new Error('setInterval Error');
25+
}
26+
27+
process.once('uncaughtException', common.mustCall((err) => {
28+
assert.strictEqual(err.message, 'setInterval Error');
29+
}));
30+
31+
process.on('exit', () => {
32+
hooks.disable();
33+
hooks.sanityCheck('Timeout');
34+
35+
checkInvocations(t1, { init: 1, before: 1, after: 1, destroy: 1 },
36+
't1: when process exits');
37+
});

0 commit comments

Comments
 (0)