【问题标题】:Handling Apollo errors on the component side在组件端处理 Apollo 错误
【发布时间】:2018-07-24 00:40:15
【问题描述】:

问题

我如何反应组件中的 Apollo 错误?

例如,如果抛出“网络离线”错误,我想显示一个红色横幅;如果显示某种类型的错误,则显示模态;如果抛出另一种错误,则呈现<Redirect>(来自react-routed-dom)。

我尝试了什么

我阅读了文档chapter about error handling,但它只解释了如何设置一个充当请求中间件的 Apollo 链接,以便在那里捕获错误。据我所知,鉴于它是一个终止链接,因此不可能将该链接中的数据向下传递给组件。

我尝试使用error boundary components,但似乎并没有真正抛出 Apollo 错误。即使使用await 语法也不会。

【问题讨论】:

  • 如果投反对票的人想解释他们的投反对票,那会很有帮助。
  • 为什么有人会对一个问题投反对票(实际上是 2 票)?
  • 到处都是巨魔……

标签: javascript reactjs graphql apollo react-apollo


【解决方案1】:

我通过将查询的 errorPolicy 设置为 none 来解决我的问题,然后您可以捕获从查询中抛出的 graphQLErrors 对象。

示例

yourQuery()
    .then()
    .catch((error) => { error.graphQLErrors });

【讨论】:

    【解决方案2】:

    正如您已经指出的,您可以使用 apollo-link-errorLink.

    如果您还使用react-router-dom 在页面之间进行路由,则可以使用浏览器历史记录或重定向组件重定向到带有状态对象(routing history)的错误页面。状态对象包含您要显示的错误。

    设置可能如下所示:

    • 创建浏览器历史记录

    import { History, createBrowserHistory } from 'history';
       
    /* If using Typescript, you can make this object Readonly as follows */
    export type ReadonlyBrowserHistory = Readonly<History>
    const browserHistory: ReadonlyBrowserHistory = createBrowserHistory();
    
    export default browserHistory;
    • 添加带有浏览器历史记录的路由器(带有将历史记录属性设为只读的选项

    import browserHistory from './browserHistory'
    import apolloClient from './apolloClient'
    
    ... 
    
    ReactDOM.render((
       <ApolloProvider client={apolloClient}>
          <Router history={browserHistory}>
             <App />
          </Router>
       </ApolloProvider>
    ), document.getElementById("root"));
    • 添加到 apollo 客户端的路由链接

    import browserHistory from './browserHistory'
    
    const errorLink = onError(({ networkError, graphQLErrors }) => {
       if (graphQLErrors) {
          browserHistory.push("/error", { errors: graphQLErrors });
       }
       else if (networkError) {
          browserHistory.push("/error", { errors: networkError });
       };
    });
    
    const httpLink = new HttpLink({
       uri: httpUri
    });
    
    const httpLinkWithErrorHandling = ApolloLink.from([
       errorLink,
       httpLink,
    ]);
    
    const apolloClient = new ApolloClient({
       link,
       ...
    });
    
    export default apolloClient;
    • 错误页面可以从路由位置属性中检索错误

    const ErrorPage = ({ location: { state } }) => {
    
      console.log(state);
    
      return (<div>error page</div>)
    };

    【讨论】:

    • 这不允许我在不重定向的情况下简单地改变当前页面的状态。在所有错误情况下,我都不想重定向到一个全新的页面。我只想在顶部显示一个模式错误(可以取消)或一个红色横幅,以向用户显示我们处于离线状态,但它仍然可以访问缓存中的数据。
    • 是的,你是对的。如果您想以不同的方式处理突变,则必须在回调中使用 operation 属性来处理一般错误处理。在您使用突变的组件中,您可以使用 Promise 的 .catch() 函数来处理错误并显示一个弹出窗口。我应该编辑我的答案吗?
    猜你喜欢
    • 2019-06-09
    • 2021-10-12
    • 2017-09-14
    • 2017-06-23
    • 2018-08-31
    • 2022-11-13
    • 2019-04-03
    • 2018-08-07
    • 2018-06-26
    相关资源
    最近更新 更多