Fetch does not throw by default, leading to inconsistent behaviour from react-query
jmunozz opened this issue · 1 comments
jmunozz commented
Fetch does not throw by default, leading to inconsistent behaviour from react-query
Expected behavior
I want to use react-query isError on HTTP errors like 4XX, 5XX...
Actual behavior
Fetch does not throw by default so we have to check response status before going on. React-query recommends to use like below:
useQuery({
queryKey: ['todos', todoId],
queryFn: async () => {
const response = await fetch('/todos/' + todoId)
if (!response.ok) {
throw new Error('Network response was not ok')
}
return response.json()
},
})
Instead we do not check fetch response in hook:
export const useAppQuery = ({ url, fetchInit = {}, reactQueryOptions }) => {
const authenticatedFetch = useAuthenticatedFetch();
const fetch = useMemo(() => {
return async () => {
const response = await authenticatedFetch(url, fetchInit);
return response.json();
};
}, [url, JSON.stringify(fetchInit)]);
return useQuery(url, fetch, {
...reactQueryOptions,
refetchOnWindowFocus: false,
});
};
One solution would be forcing fetch to throw on HTTP errors.
pnmcosta commented
experienced the same issue, changed my code to:
const authenticatedFetch = useAuthenticatedFetch();
const fetch = useMemo(() => {
return async () => {
const response = await authenticatedFetch(url, fetchInit);
if (!response.ok) {
throw new Error(`failed fetch (${url})`)
}
return response.json();
};
}, [url, JSON.stringify(fetchInit)]);
return useQuery(url, fetch, {
...reactQueryOptions,
refetchOnWindowFocus: false,
});
};
Do note this kicks in default query retries (3) see https://tanstack.com/query/v4/docs/react/guides/query-retries if you haven't specified your own option.