statelyai / xstate

Actor-based state management & orchestration for complex app logic.
https://stately.ai/docs
MIT License
27.17k stars 1.26k forks source link

Bug: Timeout of `Infinity` causes `waitFor` to reject immediately #3214

Closed tom-sherman closed 2 years ago

tom-sherman commented 2 years ago

Description

This is caused by the use of setTimeout - setTimeout(fn, Infinity) invokes fn immediately.

Expected result

Either:

I think the second option is better as it allows for deferring the timeout to the user. I agree that a timeout is the right default but there are definitely scenarios where you want to handle that yourself.

Actual result

Instant rejection of the promise returned by waitFor

Reproduction

https://codesandbox.io/s/stoic-browser-ev9s97?file=/src/index.js

Additional context

No response

davidkpiano commented 2 years ago

I agree with the second option - removing the timeout. Can you make a PR for this? 🙏

tom-sherman commented 2 years ago

On it!

tom-sherman commented 2 years ago

Do we want to error when passed -Infinity? And if so, should this be a synchronous or asynchronous error?

Andarist commented 2 years ago

@tom-sherman from the spec:

If timeout is less than 0, then set timeout to 0.

So I'm OK with just ignoring -Infinity and let the handler to be invoked immediately~ in that case.

tom-sherman commented 2 years ago

Fair enough. Although I think deferring to the spec is a bit leaky, I wouldn't expect users to know that waitFor uses setTimeout under the hood.

Andarist commented 2 years ago

We can add a dev-only warning about negative numbers - that would handle more cases without special-casing -Infinity