如何防止我的 Apollo 客户端错误处理程序(onError,错误链接)因同一错误被调用两次?

Posted

技术标签:

【中文标题】如何防止我的 Apollo 客户端错误处理程序(onError,错误链接)因同一错误被调用两次?【英文标题】:How to prevent that my Apollo Client error handler (onError, error link) is called twice for the same error? 【发布时间】:2021-10-23 01:03:20 【问题描述】:

我正在尝试为使用 Apollo 客户端 3.4.8 的 React 应用程序实现全局错误处理。

我正在这样设置 App 和 Apollo:

const client = new ApolloClient(
  cache: cacheInstance,
  credentials: 'include',
  uri: configuration.API,
  typeDefs,
);

ReactDOM.render(
  <StrictMode>
    <ApolloProvider client=client>
      <App />
    </ApolloProvider>
  </StrictMode>,
  document.getElementById('root')
);

稍后在&lt;App /&gt; 里面我添加了一个errorLink

const errorLink = onError(( graphQLErrors, networkError ) => 
  if (graphQLErrors) 
    message.error('GraphqlError');
  
  if (networkError) 
    message.error('NetworkError');
  
);
client.setLink(from([errorLink, client.link]));

当服务器以502 Bad Gateway 响应时,错误处理程序会因同一错误被调用两次。

第一次来自http/createHttpLink.ts

...
            observer.next(err.result);
          
          observer.error(err);
        );

      return () => 
...

...第二次来自error/index.ts

...
              return;
            
            observer.error(networkError);
          ,
          complete: () => 
...

为什么会出现onError 被调用两次以及如何防止?

我怀疑我的链接设置错误?


链接链似乎有问题:

  console.log(client.link);
  client.setLink(from([errorLink, client.link]));
  console.log(client.link);

这会导致:

【问题讨论】:

您能否在致电client.setLink 之前和之后检查client.link 中的内容 @diedu 你想看看哪些链接已经在链中吗? console.log(client.link) 不包含该信息。如何检查链接?也许真正的问题是,如何在终止链接之前注入一个链接,客户端由useApolloClient() 检索。 是的,对于第一个 console.log,您应该看到类似对象或函数的内容,对于 setLink 之后的第二个,它应该是一个包含 2 个元素的数组,您能确认一下吗? 肯定有问题。我已经更新了问题。 不一定是错的。也许它不像我认为的那样有效。我担心错误链接被添加了两次,但我想我们无法确认。您可以尝试像在docs link: from([errorLink, httpLink]), 中那样添加一个HttpLink 而不是将URI 传递给apollo 客户端以避免使用setLink 【参考方案1】:

所以,这里的问题是我们无法替换链中的链接,并且在这样做时:

client.setLink(from([errorLink, client.link]));

我们可以添加多个错误处理程序。

解决方案是再次应用我们需要的所有链接 + 我们要设置的新错误处理程序

// create the HttpLink somewhere and make it available globally
const link = new HttpLink(
  uri: "http://localhost:4000/graphql"
  // Additional options
);

...

// somewhere where we need a different error handler
client.setLink(from([errorLink, httpLink]));

【讨论】:

以上是关于如何防止我的 Apollo 客户端错误处理程序(onError,错误链接)因同一错误被调用两次?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 apollo 客户端在 graphql 的角度处理错误?

如何使用 React Apollo 客户端处理 HTTP 状态错误

如何使用 Apollo 客户端 useQuery 钩子防止不必要的重新获取?

如何在前端 apollo-client 上处理来自 Node/Koa 的后端错误

如何使用 React-Apollo 处理 GraphQL 错误?

如何防止 Apollo 客户端查询在 IE11 中缓存?