From 2b28b22055d1bd45224af179490fcfbe8f5e9a6b Mon Sep 17 00:00:00 2001 From: S-jooyoung Date: Thu, 3 Sep 2026 14:48:30 +0900 Subject: [PATCH] fix(preact-query): retry on mount for falsy errors when throwOnError returns false `ensurePreventErrorBoundaryRetry` only evaluated a function-valued `throwOnError` when `query.state.error` was truthy. For a query that rejected with a falsy value (e.g. `undefined`), the callback was skipped and the function itself was treated as truthy, so `retryOnMount` was disabled even though `throwOnError` would have returned `false`. Check `query.state.status === 'error'` instead so the callback runs for every failed query. Ports #11328 to preact-query. --- .../preact-falsy-error-retry-on-mount.md | 5 ++++ .../src/__tests__/useQuery.test.tsx | 29 +++++++++++++++++++ .../preact-query/src/errorBoundaryUtils.ts | 12 +++++--- 3 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 .changeset/preact-falsy-error-retry-on-mount.md diff --git a/.changeset/preact-falsy-error-retry-on-mount.md b/.changeset/preact-falsy-error-retry-on-mount.md new file mode 100644 index 00000000000..221f243fa55 --- /dev/null +++ b/.changeset/preact-falsy-error-retry-on-mount.md @@ -0,0 +1,5 @@ +--- +'@tanstack/preact-query': patch +--- + +Allow queries with falsy errors to retry on mount when `throwOnError` returns false. diff --git a/packages/preact-query/src/__tests__/useQuery.test.tsx b/packages/preact-query/src/__tests__/useQuery.test.tsx index 554a4787fad..2e524940dee 100644 --- a/packages/preact-query/src/__tests__/useQuery.test.tsx +++ b/packages/preact-query/src/__tests__/useQuery.test.tsx @@ -6951,4 +6951,33 @@ describe('useQuery', () => { expect(fetchCount).toBe(initialFetchCount + 1) expect(queryFn).toHaveBeenCalledTimes(2) }) + + it('should retry on mount when throwOnError returns false for a falsy error', async () => { + const key = queryKey() + const queryFn = vi.fn(() => Promise.reject()) + + function Component() { + const { status } = useQuery({ + queryKey: key, + queryFn, + throwOnError: () => false, + retryOnMount: () => true, + staleTime: Infinity, + retry: false, + }) + + return
{status}
+ } + + const rendered1 = renderWithClient(queryClient, ) + await vi.advanceTimersByTimeAsync(0) + expect(rendered1.getByTestId('status')).toHaveTextContent('error') + expect(queryFn).toHaveBeenCalledTimes(1) + rendered1.unmount() + + const rendered2 = renderWithClient(queryClient, ) + await vi.advanceTimersByTimeAsync(0) + expect(rendered2.getByTestId('status')).toHaveTextContent('error') + expect(queryFn).toHaveBeenCalledTimes(2) + }) }) diff --git a/packages/preact-query/src/errorBoundaryUtils.ts b/packages/preact-query/src/errorBoundaryUtils.ts index 98cab52351c..cff311741a2 100644 --- a/packages/preact-query/src/errorBoundaryUtils.ts +++ b/packages/preact-query/src/errorBoundaryUtils.ts @@ -27,10 +27,14 @@ export const ensurePreventErrorBoundaryRetry = < errorResetBoundary: QueryErrorResetBoundaryValue, query: Query | undefined, ) => { - const throwOnError = - query?.state.error && typeof options.throwOnError === 'function' - ? shouldThrowError(options.throwOnError, [query.state.error, query]) - : options.throwOnError + let throwOnError = options.throwOnError + + if (query?.state.status === 'error' && typeof throwOnError === 'function') { + throwOnError = shouldThrowError(throwOnError, [ + query.state.error as TError, + query, + ]) + } if (options.suspense || throwOnError) { // Prevent retrying failed query if the error boundary has not been reset yet