在客户端处理 apollo-server 错误

Posted

技术标签:

【中文标题】在客户端处理 apollo-server 错误【英文标题】:handling apollo-server errors on client 【发布时间】:2019-06-09 10:46:52 【问题描述】:

我在做什么?:

我想在 apollo-server 上抛出一个错误并在客户端处理它。

注意:我在 apollo-client 上使用 apollo-link-error 中间件。

服务器:

import  UserInputError  from "apollo-server";

 Mutation:      
    someMutation :  
     try 
       // here is some code which failed
       catch (error)  
// base Error class has message property by default 
// response just hold some additional informations 
       throw new UserInputError(error.message,  response );
      
    
  

客户:

我的突变在客户端的简化实现

    <Mutation
       mutation=CREATE_ORDER
     >
        (createOrder,  loading, error ) => (
        ....
         try 
           await createOrder(  variables: ...);
          catch (createOrderError) 
          //  here I get Cannot read property 'data' of undefined
            console.log(createOrderError);

          

         )
   </Mutation>

我在客户端收到以下错误(在上面代码中的 catch 子句中):

TypeError: Cannot read property 'data' of undefined
    at Mutation._this.onMutationCompleted (react-apollo.browser.umd.js:631)
    at react-apollo.browser.umd.js:586

这个错误看起来像是 httpLink 的问题。

响应:(来自 chrome 开发工具中的网络标签)

来自 graphql 规范:

如果在执行过程中遇到阻止 有效响应,响应中的数据条目应为空。

所以我假设我来自服务器的响应是有效的。数据对象应为空。

我预计会发生什么?:

我想访问来自 apollo 服务器的响应我怎样才能做到这一点?

感谢您的帮助!

【问题讨论】:

【参考方案1】:

在访问从查询或变异返回的数据之前要检查的事项

    如果加载 -> 返回一些加载器组件 如果存在错误 -> 显示一些错误组件

如果以上两个条件都不匹配,那么你肯定有数据。

除此之外你还需要有

1.在 Apollo 客户端 "errorPolicy"

 const client = new ApolloClient(
    defaultOptions: 
      watchQuery: 
        errorPolicy: 'all'
      ,
      query: 
        errorPolicy: 'all'
      ,
      mutate: 
        errorPolicy: 'all'
      
    ,
    link,
    cache,
    connectToDevTools: true,
  )

2.用于自定义服务器发送的错误 -

你可以使用formatError

const server = new ApolloServer(
  ...root,
  resolverValidationOptions: 
    requireResolversForResolveType: false,
  ,
  formatError, <---------- send custom error
  formatResponse: (response, query) => formatResponse( response, query ),
  dataSources,
  context: async ( req, res ) => 
    const user = req.user;
    return  user, req, res ;
  
);

例如

const formatError = (error) => 
  const  extensions  = error;
  logger.error(error);

  const exception = extensions.exception ? extensions.exception : ;
  logger.error('\nStackTrace');
  logger.error(exception.stacktrace);
  exception.stacktrace = null;
  const extractedError = extractErrorFromExtention(extensions);

  return extractedError ||  message: error.message, code: extensions.code, exception ;
;

【讨论】:

感谢您的回答,但问题出在 apollo-link-error 中间件 @Morty 你能详细说明你的解决方案吗?我在使用 MockedProvider 的测试中遇到了同样的问题 更新:一些底层错误未正确抛出,因此仅在浏览器控制台中可见,但在服务器测试中不可见。 errorPolicy 不会改变任何东西

以上是关于在客户端处理 apollo-server 错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在本地网络上部署带有 apollo 客户端和 apollo-server 后端的 React 应用程序

与 apollo-server 的 Websocket 连接为 connectionParams 返回乱码

在 Heroku 上部署 react/apollo-server 应用程序

来自 GraphQL 网站的 Apollo-server 教程产生错误

如何修复错误:使用 graphql 在 apollo-server 中多次定义类型“Extra”

当我尝试使用 createReadStream 通过 apollo-server 上传文件时出现此错误,