Why is my console logging: `TimeoutOverflowWarning: 4294967296000 does not fit into a 32-bit signed integer`
Asked Answered
F

4

11

I am following the course stream-adventure. One of the assignments is to make an http server which converts all the requests to uppercase and return it in the response.

Now I managed to get it working and the assignment passes. However, the console gives me a TimeoutOverflowWarning.

(node:15710) TimeoutOverflowWarning: 4294967296000 does not fit into a 32-bit signed integer.
Timer duration was truncated to 2147483647.
(node:15710) TimeoutOverflowWarning: 4294967296000 does not fit into a 32-bit signed integer.
Timer duration was truncated to 2147483647.

I'm wondering if it's a memory leak or something caused by my code, or if it is something else. Because in the error message 32-bit is mentioned, I wonder if it's related to that I'm using a Macbook Pro from 2016 which runs in 64 bit. (node v10.17.0)

The code:

'use-strict'
const through = require('through2')
const http = require('http')
const port = process.argv[2]

const uppercaser = through(function (buffer, _, next) {
  this.push(buffer.toString().toUpperCase())
  next()
});

const server = http.createServer(function (req, res) {
  if (req.method === 'POST') {
    res.writeHead(200,  { 'Content-Type': 'text/plain' })
    req.pipe(uppercaser).pipe(res)
  } else {
    res.writeHead(404)
    res.end()
  }
});

server.listen(port)

Google searches give various causes of this problem (example 1, example 2) and it seems that most of the solutions are fixed in library used.

Facelift answered 1/3, 2020 at 10:24 Comment(0)
H
8

This is the problem related to setTimeout \ setInterval functions. They have a limit of 32-bit as you can see. So that the node is warning you about it:

> setTimeout(console.log, +Infinity)

> (node:19903) TimeoutOverflowWarning: Infinity does not fit into a 32-bit signed integer.
Timeout duration was set to 1.

Since your code does not have any of those, it seems like the problem with some code in library.

I'd recommend to run node with --trace-warnings flag to find the source of warning:

--trace-warnings

Print stack traces for process warnings (including deprecations).

Hotchpot answered 25/5, 2020 at 13:14 Comment(0)
U
8

When I find this type of error is when I use a setInterval function.

This is because the upper limit of the timeout is 2147483647 which is the max limit of 32-bit int.

If you want you can make your own setInterval wrapper

function setDaysTimeout(callback,days) {
    // 86400 seconds in a day
    let msInDay = 86400*1000; 

    let dayCount = 0;
    let timer = setInterval(function() {
        dayCount++;  // a day has passed

        if (dayCount === days) {
           clearInterval(timer);
           callback.apply(this, []);
        }
    }, msInDay);
}

And use it like this:

setDaysTimeout(function() {
     console.log('Four days gone');
}, 4); // fire after 4 days
Unshakable answered 25/5, 2020 at 12:54 Comment(0)
H
8

This is the problem related to setTimeout \ setInterval functions. They have a limit of 32-bit as you can see. So that the node is warning you about it:

> setTimeout(console.log, +Infinity)

> (node:19903) TimeoutOverflowWarning: Infinity does not fit into a 32-bit signed integer.
Timeout duration was set to 1.

Since your code does not have any of those, it seems like the problem with some code in library.

I'd recommend to run node with --trace-warnings flag to find the source of warning:

--trace-warnings

Print stack traces for process warnings (including deprecations).

Hotchpot answered 25/5, 2020 at 13:14 Comment(0)
T
0

The upper limit of the timeout is 2147483647, which is the max limit of 32-bit int. In order to avoid this you can wait for the max time and then wait for any remaining time.

const timeout = async (callback, time, callbackArguments) => {
  if (!callback || typeof callback !== 'function') throw new Error('Invalid Callback')
  let args = ((callbackArguments && typeof callbackArguments === 'object' && 
    callbackArguments.length > 0) ? callbackArguments : [])
  let max = 2147483647
  if (time > max) {
    let t = Math.floor(time / max)
    let r = time%max
    for (let i = 0; i < t; i++) await (() => new Promise(res => setTimeout(() => res(), max)))();
    if (r) {
        return setTimeout(() => callback(...args), r)
    } else {
        return callback(...args)
    }
  } else {
    return setTimeout(() => callback(...args), time)
  }
}

Use like so

let a = 2
let b = 5
let c = (a, b) => console.log(!a && !b ? 0 : !a && b ? b : a && !b ? a : a + b)
let now = new Date().getTime()
let later = now + 2147483647*5
timeout(c, later-now, [a,b])
Tristatristam answered 10/5, 2021 at 16:47 Comment(1)
Could you extend your answer with an explanation of why code from the question didn't workEntelechy
D
0

I wrote a simple extension over original setTimeout to accept any timeout values.

const xSetTimeout = (() => {
    const MAX_INT = 2 ** 31 - 1;

    return function _xSetTimeout(cb, timeout) {
        if (timeout <= MAX_INT)
            return setTimeout(cb, timeout);
        return setTimeout(
            () => _xSetTimeout(cb, timeout - MAX_INT),
            MAX_INT);
    }
})();    
Disaccharide answered 19/3 at 22:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.