How to execute an async fetch request and then retry last failed request?

前端 未结 2 1773
一生所求
一生所求 2020-12-23 14:52

Apollo link offers an error handler onError

Issue: Currently, we wish to refresh oauth tokens when they expires during an apollo call and we are una

2条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-23 15:39

    I'm refreshing the token this way (updated OP's):

    import { ApolloClient } from 'apollo-client';
    import { onError } from 'apollo-link-error';
    import { ApolloLink, Observable } from 'apollo-link';  // add Observable
    
    // Define Http link
    const httpLink = new createHttpLink({
      uri: '/my-graphql-endpoint',
      credentials: 'include'
    });
    
    // Add on error handler for apollo link
    
    return new ApolloClient({
      link: ApolloLink.from([
        onError(({ graphQLErrors, networkError, operation, forward }) => {
          // User access token has expired
          if (graphQLErrors && graphQLErrors[0].message === 'Unauthorized') {
            // We assume we have both tokens needed to run the async request
            if (refreshToken && clientToken) {
              // Let's refresh token through async request
              return new Observable(observer => {
                authAPI.requestRefreshToken(refreshToken, clientToken)
                  .then(refreshResponse => {
                    operation.setContext(({ headers = {} }) => ({
                      headers: {
                        // Re-add old headers
                        ...headers,
                        // Switch out old access token for new one
                        authorization: `Bearer ${refreshResponse.access_token}` || null,
                      }
                    }));
                  })
                  .then(() => {
                    const subscriber = {
                      next: observer.next.bind(observer),
                      error: observer.error.bind(observer),
                      complete: observer.complete.bind(observer)
                    };
    
                    // Retry last failed request
                    forward(operation).subscribe(subscriber);
                  })
                  .catch(error => {
                    // No refresh or client token available, we force user to login
                    observer.error(error);
                  });
              });
            }
          }
        })
      ])
    });
    

提交回复
热议问题