Skip to content
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

feat(query-core): Expose retry error as failureReason #4315

Merged
merged 5 commits into from
Oct 22, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions docs/reference/useMutation.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const {
isLoading,
isPaused,
isSuccess,
failureCount,
failureReason,
mutate,
mutateAsync,
reset,
Expand Down Expand Up @@ -129,3 +131,11 @@ mutate(variables, {
- The error object for the query, if an error was encountered.
- `reset: () => void`
- A function to clean the mutation internal state (i.e., it resets the mutation to its initial state).
- `failureCount: number`
- The failure count for the mutation.
- Incremented every time the mutation fails.
- Reset to `0` when the mutation succeeds.
- `failureReason: null | TError`
- The failure reason for the mutation retry.
- Reset to `null` when the mutation succeeds.

4 changes: 4 additions & 0 deletions docs/reference/useQuery.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const {
error,
errorUpdatedAt,
failureCount,
failureReason,
isError,
isFetched,
isFetchedAfterMount,
Expand Down Expand Up @@ -251,6 +252,9 @@ const result = useQuery({
- The failure count for the query.
- Incremented every time the query fails.
- Reset to `0` when the query succeeds.
- `failureReason: null | TError`
- The failure reason for the query retry.
- Reset to `null` when the query succeeds.
- `errorUpdateCount: number`
- The sum of all errors.
- `refetch: (options: { throwOnError: boolean, cancelRefetch: boolean }) => Promise<UseQueryResult>`
Expand Down
18 changes: 13 additions & 5 deletions packages/query-core/src/mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,16 @@ export interface MutationState<
data: TData | undefined
error: TError | null
failureCount: number
failureReason: TError | null
isPaused: boolean
status: MutationStatus
variables: TVariables | undefined
}

interface FailedAction {
interface FailedAction<TError> {
type: 'failed'
failureCount: number
error: TError | null
}

interface LoadingAction<TVariables, TContext> {
Expand Down Expand Up @@ -71,7 +74,7 @@ interface SetStateAction<TData, TError, TVariables, TContext> {
export type Action<TData, TError, TVariables, TContext> =
| ContinueAction
| ErrorAction<TError>
| FailedAction
| FailedAction<TError>
| LoadingAction<TVariables, TContext>
| PauseAction
| SetStateAction<TData, TError, TVariables, TContext>
Expand Down Expand Up @@ -171,8 +174,8 @@ export class Mutation<
}
return this.options.mutationFn(this.state.variables!)
},
onFail: () => {
this.dispatch({ type: 'failed' })
onFail: (failureCount, error) => {
this.dispatch({ type: 'failed', failureCount, error })
},
onPause: () => {
this.dispatch({ type: 'pause' })
Expand Down Expand Up @@ -272,7 +275,8 @@ export class Mutation<
case 'failed':
return {
...state,
failureCount: state.failureCount + 1,
failureCount: action.failureCount,
failureReason: action.error,
}
case 'pause':
return {
Expand All @@ -298,6 +302,8 @@ export class Mutation<
return {
...state,
data: action.data,
failureCount: 0,
failureReason: null,
Kuirak marked this conversation as resolved.
Show resolved Hide resolved
error: null,
status: 'success',
isPaused: false,
Expand All @@ -308,6 +314,7 @@ export class Mutation<
data: undefined,
error: action.error,
failureCount: state.failureCount + 1,
failureReason: action.error,
isPaused: false,
status: 'error',
}
Expand Down Expand Up @@ -344,6 +351,7 @@ export function getDefaultState<
data: undefined,
error: null,
failureCount: 0,
failureReason: null,
isPaused: false,
status: 'idle',
variables: undefined,
Expand Down
18 changes: 13 additions & 5 deletions packages/query-core/src/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export interface QueryState<TData = unknown, TError = unknown> {
errorUpdateCount: number
errorUpdatedAt: number
fetchFailureCount: number
fetchFailureReason: TError | null
fetchMeta: any
isInvalidated: boolean
status: QueryStatus
Expand Down Expand Up @@ -82,8 +83,10 @@ export interface FetchOptions {
meta?: any
}

interface FailedAction {
interface FailedAction<TError> {
type: 'failed'
failureCount: number
error: TError
}

interface FetchAction {
Expand Down Expand Up @@ -124,7 +127,7 @@ interface SetStateAction<TData, TError> {
export type Action<TData, TError> =
| ContinueAction
| ErrorAction<TError>
| FailedAction
| FailedAction<TError>
| FetchAction
| InvalidateAction
| PauseAction
Expand Down Expand Up @@ -473,8 +476,8 @@ export class Query<
this.isFetchingOptimistic = false
},
onError,
onFail: () => {
this.dispatch({ type: 'failed' })
onFail: (failureCount, error) => {
this.dispatch({ type: 'failed', failureCount, error })
},
onPause: () => {
this.dispatch({ type: 'pause' })
Expand All @@ -500,7 +503,8 @@ export class Query<
case 'failed':
return {
...state,
fetchFailureCount: state.fetchFailureCount + 1,
fetchFailureCount: action.failureCount,
fetchFailureReason: action.error,
}
case 'pause':
return {
Expand All @@ -516,6 +520,7 @@ export class Query<
return {
...state,
fetchFailureCount: 0,
fetchFailureReason: null,
fetchMeta: action.meta ?? null,
fetchStatus: canFetch(this.options.networkMode)
? 'fetching'
Expand All @@ -537,6 +542,7 @@ export class Query<
...(!action.manual && {
fetchStatus: 'idle',
fetchFailureCount: 0,
fetchFailureReason: null,
}),
}
case 'error':
Expand All @@ -552,6 +558,7 @@ export class Query<
errorUpdateCount: state.errorUpdateCount + 1,
errorUpdatedAt: Date.now(),
fetchFailureCount: state.fetchFailureCount + 1,
fetchFailureReason: error as TError,
fetchStatus: 'idle',
status: 'error',
}
Expand Down Expand Up @@ -611,6 +618,7 @@ function getDefaultState<
errorUpdateCount: 0,
errorUpdatedAt: 0,
fetchFailureCount: 0,
fetchFailureReason: null,
fetchMeta: null,
isInvalidated: false,
status: hasData ? 'success' : 'loading',
Expand Down
1 change: 1 addition & 0 deletions packages/query-core/src/queryObserver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@ export class QueryObserver<
error,
errorUpdatedAt,
failureCount: state.fetchFailureCount,
failureReason: state.fetchFailureReason,
errorUpdateCount: state.errorUpdateCount,
isFetched: state.dataUpdateCount > 0 || state.errorUpdateCount > 0,
isFetchedAfterMount:
Expand Down
14 changes: 13 additions & 1 deletion packages/query-core/src/tests/mutations.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ describe('mutations', () => {
data: undefined,
error: null,
failureCount: 0,
failureReason: null,
isError: false,
isIdle: true,
isLoading: false,
Expand All @@ -97,6 +98,7 @@ describe('mutations', () => {
data: undefined,
error: null,
failureCount: 0,
failureReason: null,
isError: false,
isIdle: false,
isLoading: true,
Expand All @@ -115,6 +117,7 @@ describe('mutations', () => {
data: undefined,
error: null,
failureCount: 0,
failureReason: null,
isError: false,
isIdle: false,
isLoading: true,
Expand All @@ -133,6 +136,7 @@ describe('mutations', () => {
data: 'todo',
error: null,
failureCount: 0,
failureReason: null,
isError: false,
isIdle: false,
isLoading: false,
Expand Down Expand Up @@ -172,6 +176,7 @@ describe('mutations', () => {
data: undefined,
error: null,
failureCount: 0,
failureReason: null,
isError: false,
isIdle: false,
isLoading: true,
Expand All @@ -190,6 +195,7 @@ describe('mutations', () => {
data: undefined,
error: null,
failureCount: 0,
failureReason: null,
isError: false,
isIdle: false,
isLoading: true,
Expand All @@ -208,6 +214,7 @@ describe('mutations', () => {
data: undefined,
error: null,
failureCount: 1,
failureReason: 'err',
isError: false,
isIdle: false,
isLoading: true,
Expand All @@ -226,6 +233,7 @@ describe('mutations', () => {
data: undefined,
error: 'err',
failureCount: 2,
failureReason: 'err',
isError: true,
isIdle: false,
isLoading: false,
Expand Down Expand Up @@ -264,6 +272,7 @@ describe('mutations', () => {
data: undefined,
error: null,
failureCount: 1,
failureReason: 'err',
isPaused: true,
status: 'loading',
variables: 'todo',
Expand All @@ -275,6 +284,7 @@ describe('mutations', () => {
data: undefined,
error: null,
failureCount: 1,
failureReason: 'err',
isPaused: true,
status: 'loading',
variables: 'todo',
Expand All @@ -286,7 +296,8 @@ describe('mutations', () => {
context: 'todo',
data: 'todo',
error: null,
failureCount: 1,
failureCount: 0,
failureReason: null,
isPaused: false,
status: 'success',
variables: 'todo',
Expand Down Expand Up @@ -316,6 +327,7 @@ describe('mutations', () => {
data: 'new',
error: undefined,
failureCount: 0,
failureReason: null,
isPaused: false,
status: 'success',
})
Expand Down
1 change: 1 addition & 0 deletions packages/query-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ export interface QueryObserverBaseResult<TData = unknown, TError = unknown> {
error: TError | null
errorUpdatedAt: number
failureCount: number
failureReason: TError | null
errorUpdateCount: number
isError: boolean
isFetched: boolean
Expand Down
2 changes: 2 additions & 0 deletions packages/react-query/src/__tests__/useInfiniteQuery.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ describe('useInfiniteQuery', () => {
error: null,
errorUpdatedAt: 0,
failureCount: 0,
failureReason: null,
errorUpdateCount: 0,
fetchNextPage: expect.any(Function),
fetchPreviousPage: expect.any(Function),
Expand Down Expand Up @@ -104,6 +105,7 @@ describe('useInfiniteQuery', () => {
error: null,
errorUpdatedAt: 0,
failureCount: 0,
failureReason: null,
errorUpdateCount: 0,
fetchNextPage: expect.any(Function),
fetchPreviousPage: expect.any(Function),
Expand Down
8 changes: 7 additions & 1 deletion packages/react-query/src/__tests__/useMutation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -581,21 +581,25 @@ describe('useMutation', () => {
isLoading: false,
isPaused: false,
failureCount: 0,
failureReason: null,
})
expect(states[1]).toMatchObject({
isLoading: true,
isPaused: false,
failureCount: 0,
failureReason: null,
})
expect(states[2]).toMatchObject({
isLoading: true,
isPaused: false,
failureCount: 1,
failureReason: 'oops',
})
expect(states[3]).toMatchObject({
isLoading: true,
isPaused: true,
failureCount: 1,
failureReason: 'oops',
})

onlineMock.mockReturnValue(true)
Expand All @@ -608,11 +612,13 @@ describe('useMutation', () => {
isLoading: true,
isPaused: false,
failureCount: 1,
failureReason: 'oops',
})
expect(states[5]).toMatchObject({
isLoading: false,
isPaused: false,
failureCount: 1,
failureCount: 0,
failureReason: null,
data: 'data',
})

Expand Down
Loading