Offline persistent mechanism for the error state
I am using TanStack in a React Native environment and trying to provide a smooth offline/low connection experience for users.
I use PersistQueryClientProvider with AsyncStorage, and offline mode generally works well. However, I expected mutations to persist during error retries, even if a mutation fails mid-process. This is important for users with low connectivity—we don’t want to lose their data if a mutation fails and the user closes the app.
The use case that I am trying to solve is:
If a user with a poor internet connection triggers a mutation, the request might take too long and eventually throw a timeout error. The system will retry the mutation several times based on the query client configuration. However, if the user closes the app during these retries, the mutation is lost—whereas the expectation is that the mutation operation would resume once the app is reopened.
Is it possible to persist mutations after errors, similar to how queries are persisted?
5 Replies
unwilling-turquoiseOP•10h ago
(I would like to avoid copying the logic into a custom layer that would work with Async Storage to keep retrying the promise until it completes)
manual-pink•10h ago
you can customize what you persist
we default to only successful queries because errors aren't serializable per default, and pending queries have promises that also don't serialize
but if you know how to handle these - you can customize the
PersistQueryClientProvider
set persistOptions: { dehydrateOptions: { shouldDehydrateMutation: (mutation) => ...
and return true for those you want to persistunwilling-turquoiseOP•10h ago
yes, its the same way I am doing for the offline, the only difference is that I want to keep retrying for some specific errors (timeout, 500, etc)
For my understanding, if I do something like this, would be enough:
dehydrateOptions: {
shouldDehydrateMutation: (mutation) => {
return mutation.state.isPaused || Boolean(mutation.state.error);
},
},
My question is, when calling the queryClient.resumePausedMutations(), will it consider the errors as well?
From the tests, it looks like the mutation with the error state is now persisted. The problem is that the resumePaused when it is called; it only executes the persisted mutations once, and not until it succeeds. Am I missing something?
manual-pink•9h ago
during retries, you shouldn't have errors yet
resumePausedMutations only resumes paused mutations. If the mutation isn't paused, it won't be resumed
The error can't persist unless you have a custom serializer. Error instances are not JSON serializable
unwilling-turquoiseOP•8h ago
I will try to use this https://www.npmjs.com/package/superjson