persistQueryClientSubscribe calls persistQueryClientSave(props) on every cache event, but it doesn't handle the returned promise. So if saving fails, I get an unhandled promise rejection on each cache update.
I noticed this while reading the code and confirmed it with a test. It can happen with a custom persister like the IndexedDB example in the docs, because set() from idb-keyval can reject, for example with QuotaExceededError or DataCloneError. It can also happen with the built-in persisters if a dehydrateOptions callback like shouldDehydrateQuery throws.
Small repro:
const queryClient = new QueryClient()
persistQueryClientSubscribe({
queryClient,
persister: {
persistClient: () => Promise.reject(new Error('quota exceeded')),
restoreClient: () => undefined,
removeClient: () => undefined,
},
})
queryClient.setQueryData(['a'], 1) // -> unhandled rejection
This affects all the persist providers, since they all use persistQueryClientSubscribe. That includes Vue's clientPersister when it's used with persistQueryClient().
The restore side already catches errors and logs a warning in dev (#8969), but the save side doesn't. I know error handling has mostly been left to the persister (#3527), so I'm not sure which way you'd prefer:
- catch it in
persistQueryClientSubscribe and log in dev, same as restore
- keep the code as is, and add a
try/catch to the IndexedDB example in the docs
I'm happy to send a PR for either one.
persistQueryClientSubscribecallspersistQueryClientSave(props)on every cache event, but it doesn't handle the returned promise. So if saving fails, I get an unhandled promise rejection on each cache update.I noticed this while reading the code and confirmed it with a test. It can happen with a custom persister like the IndexedDB example in the docs, because
set()from idb-keyval can reject, for example withQuotaExceededErrororDataCloneError. It can also happen with the built-in persisters if adehydrateOptionscallback likeshouldDehydrateQuerythrows.Small repro:
This affects all the persist providers, since they all use
persistQueryClientSubscribe. That includes Vue'sclientPersisterwhen it's used withpersistQueryClient().The restore side already catches errors and logs a warning in dev (#8969), but the save side doesn't. I know error handling has mostly been left to the persister (#3527), so I'm not sure which way you'd prefer:
persistQueryClientSubscribeand log in dev, same as restoretry/catchto the IndexedDB example in the docsI'm happy to send a PR for either one.