question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Delaying for more than ~24.8 days causes TimeoutOverflowWarning and immediate promise resolution

See original GitHub issue

The default implementation of setTimeout can only accept values within the range of positive signed 32-bit integers. Passing a timeout greater than (2^31)-1 milliseconds (0x7FFFFFFF) yields a TimeoutOverflowWarning and causes the runtime to ignore the specified timeout, assuming a value of 1ms (which by the way seems a dangerous default, I would have opted for using the maximum supported value or straight out throw an error).

This unexpected behavior is not documented in the README, but rather than documenting this quirk of the runtime I’d like to propose a solution: instead of relying on the bare setTimeout, delay could use a wrapped version of it. Something like this:

const maxSupportedTimeout = 0x7fffffff;
type TimeoutContext = { id: ReturnType<typeof setTimeout> };
const defaultSetTimeout = (
  callback: (...args: any[]) => void,
  ms: number,
  timeoutContext?: Partial<TimeoutContext>
): TimeoutContext => {
  timeoutContext = timeoutContext || { id: undefined };
  if (ms > maxSupportedTimeout) {
    timeoutContext.id = setTimeout(
      defaultSetTimeout,
      maxSupportedTimeout,
      callback,
      ms - maxSupportedTimeout,
      timeoutContext
    );
  } else {
    timeoutContext.id = setTimeout(callback, ms);
  }
  return timeoutContext as TimeoutContext;
};
const defaultClearTimeout = (timeoutContext: TimeoutContext) =>
  clearTimeout(timeoutContext.id);

The timeoutContext is passed by reference, therefore each time defaultSetTimeout gets called the timeout id gets updated, so that defaultClearTimeout can always access the most recent value.

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
sindresorhuscommented, Jul 3, 2022

Alright. I’m ok with supporting any number. I also like it when users don’t have to care about implementation details. But I think the readme should note that the time will not be accurate because of clock drift and other factors and also that it’s based on a suspending clock, not a continuous clock (meaning time will pause if the machine sleeps).

1reaction
cdellacquacommented, Jun 27, 2022

24 days makes no sense

I found out about this bug because I needed a delay of more than 24 days. There definitely are (rare) situations in which it might be needed, and 24 days is quite a random threshold.

I’m not saying I disagree with throwing an error though, I’m quite on the fence on this, but leaning towards accepting any positive integer.

The “support any number” argument is more natural to me because as a user I don’t care about random setTimeout limits which are an implementation detail of the library.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Issues · sindresorhus/delay - GitHub
Delay a promise a specified amount of time. ... sindresorhus / delay Public. Sponsor ... Delaying for more than ~24.8 days causes TimeoutOverflowWarning...
Read more >
Delay with a promise - The Modern JavaScript Tutorial
Create a promise-based alternative. The function delay(ms) should return a promise. That promise should resolve after ms milliseconds, so that we can add ......
Read more >
Promise vs setTimeout - javascript - Stack Overflow
Short answer Promises have better priority than setTimeout callback function in event loop stack(or how i understand it).
Read more >
Optimise Node.js performance by avoiding broken promises
An in-depth look at promises, the Node.js event loop and developing ... in one extreme case, an event loop delay of over one...
Read more >
6 Interview Questions That Combine Promise and setTimeout
It is worth noting that step 4: when a macrotask is completed, all other microtasks are executed in turn first, and then the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found