Khotey Vitaliy
Khotey Vitaliy

Reputation: 519

Handle errors after every request in React apollo

How to create middleware which will catch all errors, for example I have request which required token, token can expired or damaged, so I need catch this errors on every request and be able to call queries and mutations.

For example: On expired token, I must refetch token and repeat request. On token damaged, I must logout user and refetch all queries. And type of error witch I need to handle can be many.

In(react-apollo docs)

networkInterface.useAfter([{
  applyAfterware({ response }, next) {
    if (response.status === 401) {
      logout();
    }
    next();
  }
}]);

I can't access to graphql error, and call queries or mutations.

Upvotes: 1

Views: 515

Answers (1)

Mjuice
Mjuice

Reputation: 1288

You can check to see if you have a token before every request is sent. If you do not have a token, you should handle that somewhere else in your application or potentially fetch another straight from the middleware function. You could make higher order component that wraps all of your components that must have a token. If for some reason there is no token, you can fetch another one and store it to localStorage if you are using the browser or asyncstorage if you are using React Native. Once you've assigned it to localStorage or asyncStorage, this middleware code snippet below will check for the token before every request you send, this includes all queries and mutations. If you find that your user doesn't have a token, you could also redirect them in your component them to a page where they must login again and then from there set the token to localstorage or asynstorage. Once again the apollo client's middleware will have access to it that way.

import ApolloClient, { createNetworkInterface } from 'apollo-client';
import { checkForSessionToken } from '../../utils/authentication';

const networkInterface = createNetworkInterface({
  uri: 'https://localhost:4000'
});

networkInterface.use([{
  applyMiddleware(req, next) {
    // Create the header object if needed.
    if (!req.options.headers) {
      req.options.headers = {};
    }

    // get the authentication token from Async storage
    // and assign it to the request object
    checkForSessionToken()
    .then(SESSION_TOKEN => {
      if (SESSION_TOKEN === null || SESSION_TOKEN === undefined {
          fetchNewToken()
          .then(SESSION_TOKEN => {
              localStorage.setItem('token', SESSION_TOKEN);
              req.options.headers.Authorization = `Bearer 
              ${SESSION_TOKEN}`;
          }
      } else {
       req.options.headers.Authorization = `Bearer ${SESSION_TOKEN}`;
      }

      next();
    })
    .catch(error => {
      fetchNewToken()
      .then(SESSION_TOKEN => {
          localStorage.setItem('token', token);
          req.options.headers.Authorization = `Bearer 
          ${SESSION_TOKEN}`;
      }

      next();
    })
  }
}]);

const client = new ApolloClient({
  networkInterface,
  dataIdFromObject: o => o.id
});

export default client;

Upvotes: 1

Related Questions