redux-toolkit: Timeout not throwing error with status TIMEOUT_ERROR
Hey, PR #2401 shows that fetchBaseQuery
should throw a TIMEOUT_ERROR
when time out delay is reached. However, I got an error without status {"message": "Aborted", "name": "AbortError"}
. I’m using
"@reduxjs/toolkit": "^1.9.0"
with "react-native": "0.70.3"
, "react": "18.1.0"
. Here is my base API:
export const BaseApi = createApi({
reducerPath: 'baseApi',
baseQuery: fetchBaseQuery({
baseUrl: Config.BASE_URL,
prepareHeaders: headers => {
const token = Preferences.getToken();
headers.set('authorization', `Bearer ${token}`);
return headers;
},
timeout: 1,
}),
tagTypes: ['Auth', 'Notification', 'Restaurant'],
endpoints: () => ({}),
});
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 2
- Comments: 16 (8 by maintainers)
It seems that there is a race condition. When a fetch request timeout calls
abort()
it could be the case thatTIMEOUT_ERROR
is returned orAbortError
.So here abort() is called: https://github.com/reduxjs/redux-toolkit/blob/f63b862ab78414cf94d6f3d16ba56c08f4af025c/packages/toolkit/src/query/fetchBaseQuery.ts#L276-L279
And here is the race condition: https://github.com/reduxjs/redux-toolkit/blob/f63b862ab78414cf94d6f3d16ba56c08f4af025c/packages/toolkit/src/createAsyncThunk.ts#L634-L644
When
api.abort()
is called, either of the two promises inPromise.race
above could resolve first.Just came across this bug myself using React Native.
The transformErrorResponse on the endpoint shows the “TIMEOUT_ERROR” but the error that actually makes it to the useQuery hook is that “AbortError” / “Aborted” one.
I also find it weird that I the case of a timeout aborting the action, even though the error is seen in the transformErrorResponse, any error returned there will not be used. The “AbortError” will ALWAYS be the error returned.
It took some time, but here I go. I made a small reproduction repo https://github.com/ifigueroap/redux-toolkit-timeout-bug Inside the
TheAPI.ts
file there is a timeout variable, if set to 10 it yieldsABORT_ERROR
in the code. If set to 1000, it will work without errors.Please let me know whether you can reproduce the issue, or if you need any further assistance.
Best regards,
Thanks, it would be greatly appreciated!
It would abort the AbortSignal, which would not do anything. The exception is thrown by
fetch
encountering an AbortSignal that is being aborted.Try it out:
has no effect apart from setting
controller.signal.aborted
totrue
.Look I really like this library, and I’m very thankful for its existence. That being said, hastily calling your users “lazy” is just, let us say, unprofessional. It’s ok if you need a reproduction repo, I get it. But it’s not ok to call names.