You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ApolloClient:onError重试失败后如何触发副作用?

ApolloClient onError重试失败后触发重定向的解决方案

针对你遇到的问题——onError链接中重试GraphQL错误失败后无法触发重定向,核心原因是Apollo为避免无限循环,不会将重试失败的错误再次传入onError链接。以下是两种可行的处理方案:

方案一:手动控制重试次数并在重试链中捕获错误

通过在请求上下文里记录重试次数,同时在重试请求的Observable流中监听最终错误,直接触发重定向:

import { onError } from "@apollo/client/link/error";
import { fromPromise } from "@apollo/client";

const errorLink = onError(({ graphQLErrors, operation, forward }) => {
  // 判断是否为认证类GraphQL错误(根据你的业务调整错误码)
  const isAuthError = graphQLErrors?.some(err => err.extensions?.code === 'UNAUTHENTICATED');
  
  if (isAuthError) {
    const retryCount = operation.getContext().retryCount || 0;
    
    // 只允许重试一次
    if (retryCount < 1) {
      return fromPromise(
        // 执行你的重新认证逻辑(比如刷新token)
        refreshAuthToken().catch(() => {
          // 刷新token本身失败,直接重定向
          window.location.href = '/unauthorized';
          throw new Error('认证刷新失败');
        })
      ).flatMap(newToken => {
        // 更新请求上下文:携带新token、标记重试次数
        operation.setContext(prevContext => ({
          ...prevContext,
          headers: {
            ...prevContext.headers,
            authorization: `Bearer ${newToken}`
          },
          retryCount: retryCount + 1
        }));
        
        // 重试请求,并监听重试后的错误
        return forward(operation).tap({
          error: () => {
            // 重试请求仍失败,触发重定向
            window.location.href = '/unauthorized';
          }
        });
      });
    }
  }
});

方案二:在重试次数耗尽时直接执行重定向

如果你的重试逻辑不需要依赖异步操作(比如刷新token),可以直接通过上下文的重试次数判断,在达到重试上限时触发重定向:

import { onError } from "@apollo/client/link/error";

const errorLink = onError(({ graphQLErrors, operation, forward }) => {
  const isAuthError = graphQLErrors?.some(err => err.extensions?.code === 'UNAUTHENTICATED');
  
  if (isAuthError) {
    const retryCount = operation.getContext().retryCount || 0;
    
    if (retryCount < 1) {
      // 调整请求参数或认证信息(比如替换token)
      operation.setContext({
        ...operation.getContext(),
        headers: { /* 更新后的请求头 */ },
        retryCount: retryCount + 1
      });
      // 重试请求
      return forward(operation);
    } else {
      // 已重试一次仍失败,直接重定向
      window.location.href = '/unauthorized';
      return null;
    }
  }
});

关键说明

  • 不要依赖onError链接接收重试失败的错误:Apollo的机制会屏蔽这类错误,防止无限循环,因此必须在重试逻辑的Observable链中直接捕获错误,或通过上下文标记的重试次数判断是否触发重定向。
  • 自定义错误判断:请根据你的业务场景调整isAuthError的判断逻辑(比如匹配特定的错误码、错误信息)。

内容的提问来源于stack exchange,提问作者Oliver Haynes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:51:30