Apollo客户端onError不重试请求

时间:2020-06-25 02:26:07

标签: react-native apollo react-apollo apollo-client

因此,根据有关apollo-link-error的apollo文档,如果onErrorforward(operation)一起使用,则可以用来处理重新认证。

所以我写了以下代码

import { ApolloClient } from 'apollo-client'
import { createHttpLink, HttpLink } from 'apollo-link-http'
import { setContext } from 'apollo-link-context'
import { InMemoryCache } from 'apollo-cache-inmemory'
import AsyncStorage from '@react-native-community/async-storage'
import { refresh } from 'react-native-app-auth'
import { onError } from 'apollo-link-error'
import { ApolloLink, from } from 'apollo-link'
import { RetryLink } from "apollo-link-retry"
import { KC_CONFIG } from '../../config/env'

const httpLink = new HttpLink({
  uri: 'graphqlEndpointOfYourchoice'
})

const authLink = setContext(async (_, { headers }) => {
  const accessToken = await AsyncStorage.getItem('accessToken')
  const unwrappedAccessToken = JSON.parse(accessToken)

  return {
    headers: {
      ...headers,
      authorization: unwrappedAccessToken ? `Bearer ${unwrappedAccessToken}` : "",
    }
  }
})

const errorLink = onError(({ graphQLErrors, networkError, operation, forward }) => {
  if (graphQLErrors) {
    AsyncStorage.getItem('refreshToken')
      .then(data => {
        const refreshToken = JSON.parse(data)
        // console.log(data)

        refresh(KC_CONFIG, {
          refreshToken,
        })
          .then(({ accessToken, refreshToken }) => {
            const oldHeaders = operation.getContext().headers
            operation.setContext({
              ...oldHeaders,
              authorization: accessToken
            })
            console.log(oldHeaders.authorization)
            console.log(accessToken)
            // console.log(refreshToken)

            AsyncStorage
              .multiSet([
                ['accessToken', JSON.stringify(accessToken)],
                ['refreshToken', JSON.stringify(refreshToken)]
              ])
            // tried putting forward() here <--------------
          })
          .catch(e => {
            if (e.message === 'Token is not active') console.log('logging out')
            else console.log('Refresh error: ' + e)
          })
      })
      .then(() => {
        console.log('Refreshed the accesstoken')
        return forward(operation)
      })
      .catch(e => {
        console.log('Storage error: ' + e)
      })
  }

  if (networkError) {
    console.log('network error: ' + networkError)
  }
  // tried putting forward() here <--------------
})

const retryLink = new RetryLink()

export const client = new ApolloClient({
  link: from([
    retryLink,
    errorLink,
    authLink,
    httpLink
  ]),
  cache: new InMemoryCache()
})

这没有达到期望的结果。 该错误会被捕获并正常运行,并按需刷新令牌,但从不执行第二个请求。

0 个答案:

没有答案