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

如何避免Apollo Client的onError错误链路对同一错误重复触发两次?

问题原因

  1. 链路重复添加:你在<App>组件内部执行client.setLink()的逻辑,在React 18的严格模式(<StrictMode>)下,组件会经历两次挂载执行,第一次执行后链路变为[errorLink实例1, 原始HttpLink],第二次执行时会在已经插入过errorLink的链路基础上,再插入第二个errorLink实例,最终链路变为[errorLink实例2, errorLink实例1, 原始HttpLink]。当网络错误触发时,两个errorLink都会执行回调,自然会弹出两次错误提示。
  2. 错误传递逻辑:默认情况下onError链接处理完错误后,会继续把错误向下传递给链路的后续节点,你没有主动终止错误传递,也会叠加重复触发的概率,该场景核心原因还是链路重复添加了errorLink。

解决方法

方案1:初始化ApolloClient时直接配置完整链路(最推荐)

不要动态修改client的链路,在创建实例的时候就把errorLink放到链路配置里,代码如下:

import { from, HttpLink } from '@apollo/client';
import { onError } from '@apollo/client/link/error';

// 先定义errorLink
const errorLink = onError(({ graphQLErrors, networkError }) => {
  if (graphQLErrors) {
    message.error('GraphqlError');
  }
  if (networkError) {
    message.error('NetworkError');
  }
  // 如果需要终止错误继续传递,可以加下面这行
  // return Observable.empty();
});

// 定义httpLink,原来的uri、credentials参数挪到这里配置
const httpLink = new HttpLink({
  uri: configuration.API,
  credentials: 'include'
});

const client = new ApolloClient({
  cache: cacheInstance,
  // 这里直接传入组合好的链路
  link: from([errorLink, httpLink]),
  typeDefs,
});

这样链路从创建之初就是固定的,不会有重复添加的问题,也符合Apollo Client的最佳实践。

方案2:如果必须动态添加链路,避免重复执行

如果你的业务场景确实需要在组件挂载后才添加errorLink,那修改动态设置的逻辑,加判断防止重复插入:

// 在App组件内
useEffect(() => {
  // 加个自定义标记,防止重复添加errorLink
  if (!client.link?._hasErrorLink) {
    const errorLink = onError(({ graphQLErrors, networkError }) => {
      if (graphQLErrors) {
        message.error('GraphqlError');
      }
      if (networkError) {
        message.error('NetworkError');
      }
    });
    const newLink = from([errorLink, client.link]);
    // 给新链路加自定义标记
    newLink._hasErrorLink = true;
    client.setLink(newLink);
  }
}, []);

如果不需要错误继续向下传递,可以在onError回调末尾返回Observable.empty(),主动终止链路的错误传递,也能避免后续其他链路节点触发重复的错误逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 19:12:01