Try refresh token and invalidate query when react-query encounters 401
Asked Answered
R

1

6

I would like to create a wrapper hook around react-query's useQuery hook so that I could catch a 401 error, attempt to refresh access token and if successfully refreshed - invalidate the original query.

Full example of what I am trying to do is here: https://codesandbox.io/s/agitated-booth-hbe12?file=/src/App.js

function useMyQUery() {
  const queryClient = useQueryClient();
  const { tryRefreshToken } = useSession();

  const query = useQuery(...arguments);

  if (query.isError && query.error?.status === 401) {
    tryRefreshToken().then((tokenRefreshSucccessful) =>
      queryClient.invalidateQueries("todos")
    );
  } else {
    return query;
  }

  return {};
}

In the example I have linked above I am able to catch the error, trigger the function tryRefetchToken, but the functions inside the useSession hook do not seem to pick up the token once it is set.

Ritual answered 17/2, 2021 at 15:43 Comment(0)
L
1

I don't think you can trigger side-effects like tryRefreshToken() or queryClient.invalidateQueries directly in the render function. Try putting these side-effects into the onError callback of useQuery, or in a useEffect. Something like:

function useMyQUery() {
  const queryClient = useQueryClient()
  const { tryRefreshToken } = useSession()

  return useQuery(key, fn, {
    onError: (error) => {
      if (error.status === 401) {
        tryRefreshToken().then((tokenRefreshSucccessful) =>
          queryClient.invalidateQueries("todos")
        )
      }
    }
  })
}
Lachman answered 17/2, 2021 at 19:37 Comment(4)
Thanks for putting me on the right path, however onError does not suppress the error from being exposed to the consumer, but what works is retry option, which accepts a callback function (retryCount, error) => ... , which works as expected and does not expose the error to the consumer unless you return false from that callback. Now the final issue that I have is that queryFn which is set up in the useSession context should read a state value token from that context, but it never gets the updated value, just the initial one.Ritual
if you want to hide the error completely, I would do the refresh directly in the queryFnLachman
I would like to keep that uncoupled from the query function and I don't want it it to disappear completely, just swallow the 401 the first time.Ritual
How would you suggest to deal with mutation <its rare but is there an easy way / approach to do it>Countermeasure

© 2022 - 2024 — McMap. All rights reserved.