Skip to content

Commit 8aafa9e

Browse files
Fishrock123MylesBorins
authored andcommitted
timers: warn on overflowed timeout duration
Cherry-pick from ayo Ayo commit log: > Previously there wasn't any clear indicator when you hit the overflow > other than possibly unexpected behavior, and I think emitting a warning > may be appropriate. > PR-URL: ayojs/ayo#71 > Reviewed-By: Scott Trinh <[email protected]> > Reviewed-By: Alexey Orlenko <[email protected]> > Reviewed-By: Stephen Belanger <[email protected]> > Reviewed-By: Anna Henningsen <[email protected]> > Reviewed-By: Benjamin Gruenbaum <[email protected]> PR-URL: #15627 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
1 parent 5eef728 commit 8aafa9e

File tree

2 files changed

+59
-2
lines changed

2 files changed

+59
-2
lines changed

lib/timers.js

+19-2
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,9 @@ exports.enroll = function(item, msecs) {
405405

406406
// Ensure that msecs fits into signed int32
407407
if (msecs > TIMEOUT_MAX) {
408+
process.emitWarning(`${msecs} does not fit into a 32-bit signed integer.` +
409+
`\nTimer duration was truncated to ${TIMEOUT_MAX}.`,
410+
'TimeoutOverflowWarning');
408411
msecs = TIMEOUT_MAX;
409412
}
410413

@@ -449,8 +452,15 @@ exports.setTimeout = setTimeout;
449452

450453
function createSingleTimeout(callback, after, args) {
451454
after *= 1; // coalesce to number or NaN
452-
if (!(after >= 1 && after <= TIMEOUT_MAX))
455+
if (!(after >= 1 && after <= TIMEOUT_MAX)) {
456+
if (after > TIMEOUT_MAX) {
457+
process.emitWarning(`${after} does not fit into` +
458+
' a 32-bit signed integer.' +
459+
'\nTimeout duration was set to 1.',
460+
'TimeoutOverflowWarning');
461+
}
453462
after = 1; // schedule on next tick, follows browser behavior
463+
}
454464

455465
var timer = new Timeout(after, callback, args);
456466
if (process.domain)
@@ -538,8 +548,15 @@ exports.setInterval = function(callback, repeat, arg1, arg2, arg3) {
538548

539549
function createRepeatTimeout(callback, repeat, args) {
540550
repeat *= 1; // coalesce to number or NaN
541-
if (!(repeat >= 1 && repeat <= TIMEOUT_MAX))
551+
if (!(repeat >= 1 && repeat <= TIMEOUT_MAX)) {
552+
if (repeat > TIMEOUT_MAX) {
553+
process.emitWarning(`${repeat} does not fit into` +
554+
' a 32-bit signed integer.' +
555+
'\nInterval duration was set to 1.',
556+
'TimeoutOverflowWarning');
557+
}
542558
repeat = 1; // schedule on next tick, follows browser behavior
559+
}
543560

544561
var timer = new Timeout(repeat, callback, args);
545562
timer._repeat = repeat;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const timers = require('timers');
6+
7+
const OVERFLOW = Math.pow(2, 31); // TIMEOUT_MAX is 2^31-1
8+
9+
function timerNotCanceled() {
10+
common.fail('Timer should be canceled');
11+
}
12+
13+
process.on('warning', common.mustCall((warning) => {
14+
const lines = warning.message.split('\n');
15+
16+
assert.strictEqual(warning.name, 'TimeoutOverflowWarning');
17+
assert.strictEqual(lines[0], `${OVERFLOW} does not fit into a 32-bit signed` +
18+
' integer.');
19+
assert.strictEqual(lines.length, 2);
20+
}, 3));
21+
22+
23+
{
24+
const timeout = setTimeout(timerNotCanceled, OVERFLOW);
25+
clearTimeout(timeout);
26+
}
27+
28+
{
29+
const interval = setInterval(timerNotCanceled, OVERFLOW);
30+
clearInterval(interval);
31+
}
32+
33+
{
34+
const timer = {
35+
_onTimeout: timerNotCanceled
36+
};
37+
timers.enroll(timer, OVERFLOW);
38+
timers.active(timer);
39+
timers.unenroll(timer);
40+
}

0 commit comments

Comments
 (0)