-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
useSuspenseQuery
does not retry after fetchQuery
returned an error
#7606
Comments
I see what's going on here. The problem is that when a suspense query errors and has no data yet, it throws an error to the error boundary. When that happens, you need to explicitly tell the library when it's fine to re-fetch the query, because react will re-render components even though they already threw the error once more before showing the error boundary. It's an implementation detail of react, but for us, it would mean another refetch attempt. So there is no refetch happening because the error boundary wasn't reset. In your example, there is no error boundary at all, that's why you see the white page. If there was an error boundary with the recommended integration, you would see the boundary and be able to reset it.
I'm not quite following here. When a route loader throws an error, it should show the route error boundary. The route component that uses |
Thanks for investigating! If I understand correctly, the case you described seems to be slightly different. The first fetch is not triggered by a suspense query, but rather by a fetchQuery (or prefetchQuery). Therefore the recommended error boundary does not catch the initial error. The second time the queryFn runs, it does not throw an error. That is why I would expect the suspense query to fetch successfully and the component to render. However the suspense query does not call the queryFn at all and instead instantly returns the error previously encountered in the fetchQuery. Here is an updated example with an error boundary.. I would expect the component with the suspense query to render in this case:
Instead the error boundary renders its fallback. It seems like the initial fetchQuery primes the query error boundary, even so it is not triggered from inside a suspense query. Is that to be expected? If so, is there a sensible way to handle this case? |
why not? you mentioned route loaders? Not sure which router you are using, but both react-router and tanstack-router integrate with error boundaries, so if you throw an error in a route loader (which
Like I said, I think that's expected. query/packages/react-query/src/errorBoundaryUtils.ts Lines 29 to 35 in 639c725
So when
it seems like you are expecting fetches triggered by One way to go about is to catch errors from
|
We are using tanstack-router and use the loader in a similar way to what is described in the tanstack-query docs. Simplified our setup looks like this: // src/routes/route.tsx
export const Route = createFileRoute('/route')({
component: () => <RouteComponent />,
loader() {
fetchQueryOne();
fetchQueryTwo();
},
});
function RouteComponent() {
const queryOne = useSuspenseQueryOne()
return (
...
<Suspense fallback="loading ...">
<NestedComponent />
</Suspense>
)
}
function NestedComponent() {
const queryTwo = useSuspenseQueryTwo()
return (
...
)
} // src/routes/__root.tsx
export const Route = createRootRoute({
component: () => {
if (!isAuthenticated()) {
return <Login />
}
return <Outlet />
},
}); We utilize the route loader to avoid waterfall loading of suspense queries but still want to control where to show a suspense fallback deeper inside the component tree. Additionally we don't render the outlet at all, when a user is not authenticated. I guess the issue with this setup is, that we do not await the queries in the loader and therefore the router error boundary does not get triggered. We also do not render the route component in case of missing authentication, so the suspense queries do not even get triggered. This results in this behavior:
From a user perspective it seems weird that the error boundary is shown with an auth error, even so she just logged in.
Thanks for the idea! I was looking for something like Other than that it might be best to rethink authentication handling in our router setup and use the redirect approach instead to avoid the route loader runs for unauthenticated users. Really appreciate your help and insights! |
Describe the bug
When using
useSuspenseQuery
in a component that is mounted after afetchQuery
with the samequeryKey
encountered an error,useSuspenseQuery
returns the same error without trying to call thequeryFn
again.Your minimal, reproducible example
https://stackblitz.com/edit/tanstack-query-hgaemq?file=src%2Findex.jsx
Steps to reproduce
Expected behavior
As a user, I would expect
useSuspenseQuery
to call thequeryFn
again, as the query cache does not hold any valid data.How often does this bug happen?
None
Screenshots or Videos
No response
Platform
Tanstack Query adapter
react-query
TanStack Query version
5.45.1
TypeScript version
No response
Additional context
We noticed this while using
fetchQuery
in a router loader in combination withuseSuspenseQuery
in the route component.The text was updated successfully, but these errors were encountered: