Skip to content

Commit 2045a3d

Browse files
committed
timers: warn on overflowed timeout duration
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#71
1 parent edc403c commit 2045a3d

2 files changed

Lines changed: 58 additions & 2 deletions

File tree

lib/timers.js

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

0 commit comments

Comments
 (0)