diff --git a/.changeset/preact-query-throwonerror-function.md b/.changeset/preact-query-throwonerror-function.md
new file mode 100644
index 00000000000..1ac753558d0
--- /dev/null
+++ b/.changeset/preact-query-throwonerror-function.md
@@ -0,0 +1,5 @@
+---
+'@tanstack/preact-query': patch
+---
+
+fix(preact-query): allow retryOnMount when throwOnError is function
diff --git a/packages/preact-query/src/__tests__/useQuery.test.tsx b/packages/preact-query/src/__tests__/useQuery.test.tsx
index e99de4e3336..f4213f63cbf 100644
--- a/packages/preact-query/src/__tests__/useQuery.test.tsx
+++ b/packages/preact-query/src/__tests__/useQuery.test.tsx
@@ -6769,4 +6769,113 @@ describe('useQuery', () => {
expect(rendered.getByTestId('data')).toHaveTextContent('undefined')
expect(queryFn).toHaveBeenCalledTimes(0)
})
+
+ it('should retry on mount when throwOnError returns false', async () => {
+ const key = queryKey()
+ let fetchCount = 0
+ const queryFn = vi.fn().mockImplementation(() => {
+ fetchCount++
+ return Promise.reject(new Error('Simulated 500 error'))
+ })
+
+ function Component() {
+ const { status, error } = useQuery({
+ queryKey: key,
+ queryFn,
+ throwOnError: () => false,
+ retryOnMount: () => true,
+ staleTime: Infinity,
+ retry: false,
+ })
+
+ return (
+
+
{status}
+ {error &&
{error.message}
}
+
+ )
+ }
+
+ const rendered1 = renderWithClient(queryClient, )
+ await vi.advanceTimersByTimeAsync(0)
+ expect(rendered1.getByTestId('status')).toHaveTextContent('error')
+ expect(fetchCount).toBe(1)
+ rendered1.unmount()
+
+ const initialFetchCount = fetchCount
+
+ const rendered2 = renderWithClient(queryClient, )
+ await vi.advanceTimersByTimeAsync(0)
+ expect(rendered2.getByTestId('status')).toHaveTextContent('error')
+
+ expect(fetchCount).toBe(initialFetchCount + 1)
+ expect(queryFn).toHaveBeenCalledTimes(2)
+ })
+
+ it('should not retry on mount when throwOnError function returns true', async () => {
+ const key = queryKey()
+ let fetchCount = 0
+ const queryFn = vi.fn().mockImplementation(() => {
+ fetchCount++
+ return Promise.reject(new Error('Simulated 500 error'))
+ })
+
+ function Component() {
+ const { status, error } = useQuery({
+ queryKey: key,
+ queryFn,
+ throwOnError: () => true,
+ retryOnMount: () => true,
+ staleTime: Infinity,
+ retry: false,
+ })
+
+ return (
+
+
{status}
+ {error &&
{error.message}
}
+
+ )
+ }
+
+ const rendered1 = renderWithClient(
+ queryClient,
+ (
+
+
error
+
{error?.message}
+
+ )}
+ >
+
+ ,
+ )
+ await vi.advanceTimersByTimeAsync(0)
+ expect(rendered1.getByTestId('status')).toHaveTextContent('error')
+ expect(fetchCount).toBe(1)
+
+ rendered1.unmount()
+
+ const initialFetchCount = fetchCount
+
+ const rendered2 = renderWithClient(
+ queryClient,
+ (
+
+
error
+
{error?.message}
+
+ )}
+ >
+
+ ,
+ )
+ await vi.advanceTimersByTimeAsync(0)
+ expect(rendered2.getByTestId('status')).toHaveTextContent('error')
+
+ expect(fetchCount).toBe(initialFetchCount)
+ expect(queryFn).toHaveBeenCalledTimes(1)
+ })
})
diff --git a/packages/preact-query/src/errorBoundaryUtils.ts b/packages/preact-query/src/errorBoundaryUtils.ts
index 0b3d561fea6..86fbccd29f1 100644
--- a/packages/preact-query/src/errorBoundaryUtils.ts
+++ b/packages/preact-query/src/errorBoundaryUtils.ts
@@ -25,11 +25,17 @@ export const ensurePreventErrorBoundaryRetry = <
TQueryKey
>,
errorResetBoundary: QueryErrorResetBoundaryValue,
+ query: Query | undefined,
) => {
+ const throwOnError =
+ query?.state.error && typeof options.throwOnError === 'function'
+ ? shouldThrowError(options.throwOnError, [query.state.error, query])
+ : options.throwOnError
+
if (
options.suspense ||
- options.throwOnError ||
- options.experimental_prefetchInRender
+ options.experimental_prefetchInRender ||
+ throwOnError
) {
// Prevent retrying failed query if the error boundary has not been reset yet
if (!errorResetBoundary.isReset()) {
diff --git a/packages/preact-query/src/useBaseQuery.ts b/packages/preact-query/src/useBaseQuery.ts
index 05ce46e7f6e..16d8e7510c5 100644
--- a/packages/preact-query/src/useBaseQuery.ts
+++ b/packages/preact-query/src/useBaseQuery.ts
@@ -71,8 +71,17 @@ export function useBaseQuery<
? 'isRestoring'
: 'optimistic'
+ const query = client
+ .getQueryCache()
+ .get<
+ TQueryFnData,
+ TError,
+ TQueryData,
+ TQueryKey
+ >(defaultedOptions.queryHash)
+
ensureSuspenseTimers(defaultedOptions)
- ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary)
+ ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary, query)
useClearResetErrorBoundary(errorResetBoundary)
diff --git a/packages/preact-query/src/useQueries.ts b/packages/preact-query/src/useQueries.ts
index be57d2aebd6..acbf8d41ed2 100644
--- a/packages/preact-query/src/useQueries.ts
+++ b/packages/preact-query/src/useQueries.ts
@@ -241,9 +241,10 @@ export function useQueries<
[queries, client, isRestoring],
)
- defaultedQueries.forEach((query) => {
- ensureSuspenseTimers(query)
- ensurePreventErrorBoundaryRetry(query, errorResetBoundary)
+ defaultedQueries.forEach((queryOptions) => {
+ ensureSuspenseTimers(queryOptions)
+ const query = client.getQueryCache().get(queryOptions.queryHash)
+ ensurePreventErrorBoundaryRetry(queryOptions, errorResetBoundary, query)
})
useClearResetErrorBoundary(errorResetBoundary)