From 0367986b0611d0be0bcdd432d4599036e9caba7b Mon Sep 17 00:00:00 2001 From: Jeremiah Senkpiel Date: Tue, 24 May 2016 16:39:54 -0400 Subject: [PATCH] timers: warn on overflowed timeout duration Perviously 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: https://github.com/nodejs/node/pull/6956 --- lib/timers.js | 13 +++++++ .../test-timers-max-duration-warning.js | 39 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 test/parallel/test-timers-max-duration-warning.js diff --git a/lib/timers.js b/lib/timers.js index 9dbae32405cf6e..42a6fe50354263 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -296,6 +296,9 @@ exports.enroll = function(item, msecs) { // Ensure that msecs fits into signed int32 if (msecs > TIMEOUT_MAX) { + process.emitWarning(`${msecs} does not fit into a 32-bit signed integer.` + + `\nTimer duration was truncated to ${TIMEOUT_MAX}.`, + 'TimeoutOverflowWarning'); msecs = TIMEOUT_MAX; } @@ -316,6 +319,11 @@ exports.setTimeout = function(callback, after) { after *= 1; // coalesce to number or NaN + if (after > TIMEOUT_MAX) { + process.emitWarning(`${after} does not fit into a 32-bit signed integer.` + + '\nTimeout duration was set to 1.', + 'TimeoutOverflowWarning'); + } if (!(after >= 1 && after <= TIMEOUT_MAX)) { after = 1; // schedule on next tick, follows browser behaviour } @@ -376,6 +384,11 @@ exports.setInterval = function(callback, repeat) { repeat *= 1; // coalesce to number or NaN + if (repeat > TIMEOUT_MAX) { + process.emitWarning(`${repeat} does not fit into a 32-bit signed integer.` + + '\nInterval duration was set to 1.', + 'TimeoutOverflowWarning'); + } if (!(repeat >= 1 && repeat <= TIMEOUT_MAX)) { repeat = 1; // schedule on next tick, follows browser behaviour } diff --git a/test/parallel/test-timers-max-duration-warning.js b/test/parallel/test-timers-max-duration-warning.js new file mode 100644 index 00000000000000..3433ce8398e2c4 --- /dev/null +++ b/test/parallel/test-timers-max-duration-warning.js @@ -0,0 +1,39 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const timers = require('timers'); + +const OVERFLOW = Math.pow(2, 31); // TIMEOUT_MAX is 2^31-1 + +function TimerNotCanceled() { + common.fail('Timer should be canceled'); +} + +process.on('warning', common.mustCall((warning) => { + const lines = warning.message.split('\n'); + + assert.strictEqual(warning.name, 'TimeoutOverflowWarning'); + assert.strictEqual(lines[0], `${OVERFLOW} does not fit into a 32-bit signed` + + ' integer.'); + assert.strictEqual(lines.length, 2); +}, 3)); + + +{ + const timeout = setTimeout(TimerNotCanceled, OVERFLOW); + clearTimeout(timeout); +} + +{ + const interval = setInterval(TimerNotCanceled, OVERFLOW); + clearInterval(interval); +} + +{ + const timer = { + _onTimeout: TimerNotCanceled + }; + timers.enroll(timer, OVERFLOW); + timers.active(timer); + timers.unenroll(timer); +}