Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

To execute the onError link when the refresh token expires upon refreshing, you can use the HttpLink from apollo-link-http and add a custom error handling logic to it. Here is an example code snippet for the same:

import { ApolloLink, Observable } from 'apollo-link';
import { HttpLink } from 'apollo-link-http';
import { onError } from 'apollo-link-error';

// create an httpLink with your uri
const httpLink = new HttpLink({ uri: YOUR_GRAPHQL_URI });

// define your error handling logic
const handleErrors = ({ graphQLErrors, networkError }) => {
  if (graphQLErrors) {
    graphQLErrors.map(({ message, locations, path }) =>
      console.log(
        `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
      ),
    );
  }

  if (networkError) {
    console.log(`[Network error]: ${networkError}`);
  }

  // check if the error contains an "Unauthorized" status code
  const unauthorizedError =
    networkError &&
    networkError.statusCode === 401 &&
    networkError.result &&
    networkError.result.errors &&
    networkError.result.errors.find(
      ({ message }) => message === 'Unauthorized',
    );

  // if the error is an "Unauthorized" error, refresh the access token and retry the request
  if (unauthorizedError) {
    return new Observable(observer => {
      // your refresh token async logic here...

      // if the refresh token succeeds, retry the request with the new access token
      const headers = {
        Authorization: `Bearer ${NEW_ACCESS_TOKEN}`,
      };
      const newHttpLink = httpLink.clone({ headers });
      const subscriber = newHttpLink.request(operation).subscribe({
        next: observer.next.bind(observer),
        error: observer.error.bind(observer),
        complete: observer.complete.bind(observer),
      });

      // unsubscribe function for clearing up if the operation is cancelled
      return () => {
        if (subscriber) subscriber.unsubscribe();
      };
    });
  }
};

// create the link chain with the error handling logic
const link = ApolloLink.from([
  onError(handleErrors),
  httpLink,
]);

// create the apollo client with the link chain
const client = new ApolloClient({
  link,
  cache: new InMemoryCache(),
});

This code utilizes ApolloLink to chain multiple links together, such as the onError link and the HttpLink. Then defines a custom error handling logic in the handleErrors function that checks for the "Unauthorized" error and refreshes the access token if required. Finally, creates an Apollo client with the defined link chain.