Skip to content

Commit ce3586d

Browse files
Fishrock123jasnell
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 4843c2f commit ce3586d

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
@@ -398,6 +398,9 @@ exports.enroll = function(item, msecs) {
398398

399399
// Ensure that msecs fits into signed int32
400400
if (msecs > TIMEOUT_MAX) {
401+
process.emitWarning(`${msecs} does not fit into a 32-bit signed integer.` +
402+
`\nTimer duration was truncated to ${TIMEOUT_MAX}.`,
403+
'TimeoutOverflowWarning');
401404
msecs = TIMEOUT_MAX;
402405
}
403406

@@ -442,8 +445,15 @@ exports.setTimeout = setTimeout;
442445

443446
function createSingleTimeout(callback, after, args) {
444447
after *= 1; // coalesce to number or NaN
445-
if (!(after >= 1 && after <= TIMEOUT_MAX))
448+
if (!(after >= 1 && after <= TIMEOUT_MAX)) {
449+
if (after > TIMEOUT_MAX) {
450+
process.emitWarning(`${after} does not fit into` +
451+
' a 32-bit signed integer.' +
452+
'\nTimeout duration was set to 1.',
453+
'TimeoutOverflowWarning');
454+
}
446455
after = 1; // schedule on next tick, follows browser behavior
456+
}
447457

448458
var timer = new Timeout(after, callback, args);
449459
if (process.domain)
@@ -531,8 +541,15 @@ exports.setInterval = function(callback, repeat, arg1, arg2, arg3) {
531541

532542
function createRepeatTimeout(callback, repeat, args) {
533543
repeat *= 1; // coalesce to number or NaN
534-
if (!(repeat >= 1 && repeat <= TIMEOUT_MAX))
544+
if (!(repeat >= 1 && repeat <= TIMEOUT_MAX)) {
545+
if (repeat > TIMEOUT_MAX) {
546+
process.emitWarning(`${repeat} does not fit into` +
547+
' a 32-bit signed integer.' +
548+
'\nInterval duration was set to 1.',
549+
'TimeoutOverflowWarning');
550+
}
535551
repeat = 1; // schedule on next tick, follows browser behavior
552+
}
536553

537554
var timer = new Timeout(repeat, callback, args);
538555
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)