Skip to content

Commit 9c8516d

Browse files
committed
fix(react-query): improve throwOnError logic with query state validation
- Pass query object to ensurePreventErrorBoundaryRetry for accurate state checking - Preserve query deduplication behavior while fixing throwOnError function handling - Fixes issue where throwOnError function couldn't access query error state
1 parent bbc9723 commit 9c8516d

File tree

4 files changed

+21
-12
lines changed

4 files changed

+21
-12
lines changed

packages/react-query/src/__tests__/useQuery.test.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6978,7 +6978,8 @@ describe('useQuery', () => {
69786978

69796979
const initialFetchCount = fetchCount
69806980

6981-
renderWithClient(queryClient,
6981+
renderWithClient(
6982+
queryClient,
69826983
<ErrorBoundary
69836984
fallbackRender={({ error }) => (
69846985
<div>
@@ -6988,7 +6989,7 @@ describe('useQuery', () => {
69886989
)}
69896990
>
69906991
<Component />
6991-
</ErrorBoundary>
6992+
</ErrorBoundary>,
69926993
)
69936994

69946995
await vi.waitFor(() =>

packages/react-query/src/errorBoundaryUtils.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,17 @@ export const ensurePreventErrorBoundaryRetry = <
2727
errorResetBoundary: QueryErrorResetBoundaryValue,
2828
query?: Query<TQueryFnData, TError, TQueryData, TQueryKey>,
2929
) => {
30-
if (
31-
options.suspense ||
32-
options.experimental_prefetchInRender
33-
) {
30+
if (options.suspense || options.experimental_prefetchInRender) {
3431
// Prevent retrying failed query if the error boundary has not been reset yet
3532
if (!errorResetBoundary.isReset()) {
3633
options.retryOnMount = false
3734
}
3835
} else if (options.throwOnError && !errorResetBoundary.isReset()) {
3936
if (typeof options.throwOnError === 'function') {
40-
if (query?.state.error && shouldThrowError(options.throwOnError, [query.state.error, query])) {
37+
if (
38+
query?.state.error &&
39+
shouldThrowError(options.throwOnError, [query.state.error, query])
40+
) {
4141
options.retryOnMount = false
4242
}
4343
} else {

packages/react-query/src/useBaseQuery.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ export function useBaseQuery<
5353
const errorResetBoundary = useQueryErrorResetBoundary()
5454
const client = useQueryClient(queryClient)
5555
const defaultedOptions = client.defaultQueryOptions(options)
56+
const query = client
57+
.getQueryCache()
58+
.get<
59+
TQueryFnData,
60+
TError,
61+
TQueryData,
62+
TQueryKey
63+
>(defaultedOptions.queryHash)
5664

5765
;(client.getDefaultOptions().queries as any)?._experimental_beforeQuery?.(
5866
defaultedOptions,
@@ -72,8 +80,7 @@ export function useBaseQuery<
7280
: 'optimistic'
7381

7482
ensureSuspenseTimers(defaultedOptions)
75-
ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary)
76-
83+
ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary, query)
7784
useClearResetErrorBoundary(errorResetBoundary)
7885

7986
// this needs to be invoked before creating the Observer because that can create a cache entry

packages/react-query/src/useQueries.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,10 @@ export function useQueries<
242242
[queries, client, isRestoring],
243243
)
244244

245-
defaultedQueries.forEach((query) => {
246-
ensureSuspenseTimers(query)
247-
ensurePreventErrorBoundaryRetry(query, errorResetBoundary)
245+
defaultedQueries.forEach((queryOptions) => {
246+
ensureSuspenseTimers(queryOptions)
247+
const query = client.getQueryCache().get(queryOptions.queryHash)
248+
ensurePreventErrorBoundaryRetry(queryOptions, errorResetBoundary, query)
248249
})
249250

250251
useClearResetErrorBoundary(errorResetBoundary)

0 commit comments

Comments
 (0)