Skip to content

Fetch does not throw by default, leading to inconsistent behaviour from react-query #201

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

Open
jmunozz opened this issue May 2, 2023 · 1 comment

Comments

@jmunozz
Copy link

jmunozz commented May 2, 2023

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.

@jmunozz jmunozz changed the title Fetch does not throw by default, leading to inconstant behaviour from react-query Fetch does not throw by default, leading to inconsistent behaviour from react-query May 2, 2023
@pnmcosta
Copy link

pnmcosta commented May 5, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants