React Query get error status code in global onError handler
Asked Answered
W

4

8

When creating the queryClient I want to create a global onError handler that refreshes my access token when the error response code is 401. But I don't know how the status code is accessible on the returned error in the onError handler.

Below is my global onError handler and I only need to access the response code in the if statement to refresh my token at the appropriate time.

const queryClient = new QueryClient({
  queryCache: new QueryCache({
    onError: async (error, query) => {
      // How to get status code fo error
      if (error.status === 401) {
        console.log("Refreshing Token");
        await api.get("/api/refresh-token");
        queryClient.refetchQueries(query.queryKey);
      }
    },
  }),
});
Westering answered 11/11, 2021 at 10:47 Comment(0)
C
3

The error is just whatever the rejected Promise has created, so it depends on how you do the actual data fetching.

If it's axios, it will likely be an AxiosError, so the status code should be available there.

If it's fetch, then it depends on how you transform your erroneous status code to a failed Promise, because fetch doesn't do that per default. If it's just:

if (!response.ok) {
  throw new Error("no ok")
}

then you don't have information about the status code at all, because you've not included it in the Error.

All in all, this is out of react-queries hands, because it is agnostic about how data fetching is done.

Cent answered 11/11, 2021 at 11:37 Comment(1)
I'm using axions but I have decided to move the logic to an axios interceptor and not handle it with React Query. Thanks for your explanationWestering
U
10

You should get it by using error.request.status.

const queryClient = new QueryClient({
  queryCache: new QueryCache({
    onError: async (error, query) => {
      // How to get status code fo error
      if (error.request.status === 401) {
        console.log("Refreshing Token");
        await api.get("/api/refresh-token");
        queryClient.refetchQueries(query.queryKey);
      }
    },
  }),
});
Unbent answered 11/11, 2021 at 11:36 Comment(4)
I don't think this is true, because it totally depends on how the data fetching as doneCent
I assume he is using axios according to the tags.Unbent
I'm using axions but I have decided to move the logic to an axios interceptor and not handle it with React QueryWestering
@Westering would you like to tell why you decide to do that? i already have that in my interceptor and i was planning to move my logic to query clientAdverse
C
3

The error is just whatever the rejected Promise has created, so it depends on how you do the actual data fetching.

If it's axios, it will likely be an AxiosError, so the status code should be available there.

If it's fetch, then it depends on how you transform your erroneous status code to a failed Promise, because fetch doesn't do that per default. If it's just:

if (!response.ok) {
  throw new Error("no ok")
}

then you don't have information about the status code at all, because you've not included it in the Error.

All in all, this is out of react-queries hands, because it is agnostic about how data fetching is done.

Cent answered 11/11, 2021 at 11:37 Comment(1)
I'm using axions but I have decided to move the logic to an axios interceptor and not handle it with React Query. Thanks for your explanationWestering
F
1

Error type is "unknown", you need to map this type. I am using fetch to do the requests and can map the error as "Response" object. If you need to consult the content of de error, could print with JSON.stringfy.

  queryCache: new QueryCache({
onError: (error) => {
  // JSON.stringify(error) if you are not secure and need to see the content, could print the error in strinfy
  const response = error as Response
  console.log('---------------------------------')
  console.log(response.status) // 401
  console.log(response.type) // default
  console.log(response.ok) // false
  console.log('---------------------------------')
}})
Footlambert answered 9/2, 2022 at 17:12 Comment(0)
P
1

Get help from typescript. For example if you're using Axios to send your requests just set the error type to AxiosError then you can see possible options in the error object.

const {data} = useQuery(['request_key'], async () => await axios.get(),
{
  onError: (err: AxiosError) => {
    if(err.response?.status === 401) {
      console.log('unauthorized')
    }
  }
})
Propylaeum answered 26/9, 2023 at 17:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.