fix(expect): race slow async poll fn against timeout deadline#9929
Open
Anas0709 wants to merge 1 commit intovitest-dev:mainfrom
Open
fix(expect): race slow async poll fn against timeout deadline#9929Anas0709 wants to merge 1 commit intovitest-dev:mainfrom
Anas0709 wants to merge 1 commit intovitest-dev:mainfrom
Conversation
When the poll callback is a slow async function, `await fn()` would block for the full duration of fn regardless of the configured timeout. The timeout flag fired correctly but couldn't interrupt the in-flight await, so tests could take orders of magnitude longer than expected or hang until the global test timeout. Fix by creating a deadline promise that rejects when the timeout fires and racing it against fn() on non-last-attempt iterations. The last attempt still awaits fn() directly to preserve the existing "one final chance" semantics. When the deadline wins the race, the last recorded assertion error (if any) is surfaced with the expected cause message so the output remains consistent with the normal timeout path. Fixes vitest-dev#9844
✅ Deploy Preview for vitest-dev ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify project configuration. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #9844
When the
expect.pollcallback is a slow async function,await fn()blocks for the full duration offnregardless of the configuredtimeout. The timeout flag fired correctly but could not interrupt the in-flightawait, so tests took orders of magnitude longer than expected (or hung until the global test timeout).Root cause: the poll loop did
await fn()unconditionally — no race against the deadline.Fix: create a deadline
Promisethat rejects when the timeout fires and usePromise.race([fn(), deadlinePromise])on non-last-attempt iterations. The last attempt stillawaitsfn()directly to preserve the existing "one final chance" semantics (_isLastPollAttempt). When the deadline wins, the last recorded assertion error (if any) is surfaced with the expectedcausemessage so output is consistent with the normal timeout path.Behaviour before / after
why 2000stuck(fn: 10 s)should handle success on last attemptTest plan
slow async fn is interrupted when timeout expires— asserts the test fails in < 1 s with"Matcher did not succeed in time."slow async fn timeout surfaces last assertion error when available— asserts the last assertion message is preserved when fn slows down after the first fast callexpect-polltests still pass acrossthreads,vmThreads, andforkspools