-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
fix(query-core): query cancellation and reverting #9293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…perative methods to achieve that, we let the retryer's `onError` "transform" the result back to potentially TData, and if so, we'll resolve the promise to that instead; that means calls to `fetchQuery` will be "successful" when a cancellation happens in the meantime, but they will then resolve to the reverted data; also, if the initial fetch is cancelled, we would still throw, as there is no data to revert to.
View your CI Pipeline Execution ↗ for commit 07c1572
☁️ Nx Cloud last updated this comment at |
Sizes for commit 07c1572:
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9293 +/- ##
===========================================
+ Coverage 45.19% 59.23% +14.04%
===========================================
Files 208 137 -71
Lines 8320 5554 -2766
Branches 1879 1493 -386
===========================================
- Hits 3760 3290 -470
+ Misses 4113 1960 -2153
+ Partials 447 304 -143 🚀 New features to boost your workflow:
|
up until now, silent reverts have only stopped the query from going into error state, but the exposed promise was still rejected now, the promise won't reject because a silent revert indicates another refetch happening, so we'd want to get that promise's result instead this also means "silent" is an internal thing that shouldn't be used by consumers, because it can lead to never resolving promises instead
clientQueryClient.clear() | ||
serverQueryClient.clear() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Ephem we now get another CancelledError
here if we clear the caches. They are local to this test, so clearing them shouldn’t be necessary, but I’m wondering where this is coming from in the first place 🤔
queryClient.fetchQuery({ | ||
queryClient.prefetchQuery({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this now throws a CancelledError
because we call cancelQueries
with revert:false
, and since we don’t revert, the error makes it to the cache. It did so before too, but since the refactor to async/await, it shows up as unhandled in node.
# Conflicts: # packages/query-core/src/query.ts
we don't want errors that get reverted internally to throw on imperative methods. to achieve that, I've:
retryer
away fromonSuccess
/onError
callbacks, because we can just use promise handling (then/catch) where the retryer is created. We do the same with mutations so this streamlines things, too.’revert’
back to the previous state. That means a revert will not trigger imperative methods to fail the promise, but it will resolve them with the data we revert to internally.fetch
again but wants tocancelRefetch: true
, which is whatinvalidateQueries
does per default. In those cases, the original promise would also reject, but we would actually like it to receive the value from the second fetch. This is now done (see the added test case), but it implies that if we cancel withsilent:true
, we need another fetch to happen. Internally, this is guaranteed, butsilent:boolean
is also exposed onqueryClient.cancelQueries
, so if you do that without triggering another fetch, the promise will be pending until a new fetch happens somehow.Generally, the exposed promise was never transformed when we had a CancelationError, which is why users kept seeing it (e.g. in route loaders)
CancelledError
on imperative methods. This wasn’t an issue when just usinguseQuery
, because the internal Query State was mapped correctly.