Apollo Client中刷新过期Token后无法重试请求的问题
解决Apollo Client 401时刷新Token后无法重试请求的问题
你的代码核心问题是:getNewTokens()的异步回调里返回forward(operation),但这个返回值没有被Apollo的错误链路捕获到——onError需要返回一个Observable来替代原请求的数据流,而你当前的写法只是在Promise回调里返回,没有把重试逻辑整合到链路中。
修正后的代码如下:
import { fromPromise } from '@apollo/client/utilities'; const getNewTokens = () => { const refreshToken = localStorage.getItem('account:refreshToken'); const accessToken = localStorage.getItem('account:accessToken'); return apolloClient .mutate({ mutation: REFRESH_TOKEN, variables: { accessToken, refreshToken } }) .then((response) => { const { tokens } = response.data.refreshTokens; localStorage.setItem('account:refreshToken', tokens.refreshToken); localStorage.setItem('account:accessToken', tokens.accessToken); return tokens; }); }; const errorLink = onError(({ graphQLErrors, networkError, operation, forward }) => { if (graphQLErrors) { graphQLErrors.forEach(({ message, locations, path }) => console.log(`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`) ); } if (networkError?.statusCode === 401) { // 将异步的token刷新操作转为Observable,融入Apollo链路 return fromPromise(getNewTokens()) .flatMap(() => { const oldHeaders = operation.getContext().headers; // 更新请求上下文的授权头 operation.setContext({ headers: { ...oldHeaders, authorization: `Bearer ${localStorage.getItem('account:accessToken')}` } }); // 重试原请求 return forward(operation); }); } });
关键改动说明
- 引入
fromPromise工具,把刷新token的Promise转为Observable,这样才能被Apollo的链路系统识别 - 将重试逻辑放到
flatMap操作符中,确保onError返回的是重试请求的Observable,让客户端能执行重试 - 优化了
networkError的判断,使用可选链避免空值报错
内容的提问来源于stack exchange,提问作者DAbuzied
相关产品推荐
相关产品推荐

