使用 express-graphql 和 react-apollo 处理错误

Posted

技术标签:

【中文标题】使用 express-graphql 和 react-apollo 处理错误【英文标题】:Error handling with express-graphql & react-apollo 【发布时间】:2018-08-01 12:26:45 【问题描述】:

我正在尝试在登录表单上显示一个简单的“电子邮件和密码不匹配”错误,但我遇到了问题,并且不确定我出错的地方是在服务器上还是在我的 React 应用程序中。我想我会在这里发帖,因为我不确定哪个 github repo 合适。 这是服务器上的解析器:

// Schema definition:

type Mutation 
   loginViewer(credentials: AUTH_CREDENTIALS): SignInPayload!


type SignInPayload 
   token: String
   expires: Int
   requiresReset: Boolean


// Mapping the mutation to the resolver:

Mutation: 
   loginViewer: loginViewerMutation,
,


// Resolver:

const loginViewerMutation = async (obj, args) => 
   const  credentials  = args
   const user = await User.findOne( email )
   if (!user) throw new GraphQLError('Email and password do not match')
   const matches = await user.comparePassword(password)
   if (!matches) throw new GraphQLError('Email and password do not match')
   return createJWT(user)

然后,在我的登录组件中调用突变:

const mutation = gql`
   mutation LoginViewer($password: String!, $email: String!) 
      loginViewer(credentials:  email: $email, password: $password ) 
         token
         expires
         requiresReset
      
   
`

export class Login extends React.Component 
   handleLogin = (credentials) => 
      this.props
         .mutate( variables:  ...credentials  )
         .then(() => 
            // ...
         )
         .catch((error) => 
            console.log(error.message)
            console.log(error.graphQLErrors)
            // ...
         )
   

   render() 
      // ...
   


export default graqphql(mutation)(Login)

当我提供正确的信息时,一切都会按预期进行。如果我不这样做,则捕获的错误不包含 GraphQLErrors。

我正在使用默认设置的 apollo-link-error 中间件:https://www.apollographql.com/docs/link/links/error.html

我的控制台如下所示:

正在返回预期的身份验证错误,并从中间件记录下来。但是,在我的 Login 组件中,error.graphQLErrors 数组是空的。

我可能哪里出错了?

返回 500 内部服务器错误似乎不正确 --- 它的行为完全符合我的要求。我是否在服务器上错误地实现了这一点?

graphQLErrors 如何在日志中间件和 .catch(error) 之间“丢失”?

【问题讨论】:

你能把loginViewerMutation连接到解析器映射的代码贴出来吗? @TalZ,刚刚用更多代码更新了问题 我尝试在我的服务器上重现类似的错误,但没有成功。不知道为什么。 【参考方案1】:

我在 express-graphql github repo 上提出了这个问题,他们很快指出解决方案是删除我的 loginViewer 突变上的 !

// Schema definition:

type Mutation 
   loginViewer(credentials: AUTH_CREDENTIALS): SignInPayload!


// Should be:

type Mutation 
   loginViewer(credentials: AUTH_CREDENTIALS): SignInPayload

这是自您的***字段 (loginViewer) 以来的预期行为 定义为非空。这意味着当错误冒泡时,GraphQL 引擎 除了使数据字段等于null之外别无选择:

由于 Non-Null 类型字段不能为 null,因此会传播字段错误 由父字段处理。如果父字段可能为空 然后它解析为 null,否则如果它是非 Null 类型,则 字段错误会进一步传播到其父字段。

如果从请求根到错误源的所有字段 返回非 Null 类型,则响应中的“数据”条目应为 空。

http://facebook.github.io/graphql/draft/#sec-Errors-and-Non-Nullability

如果 data 为 null 则意味着整个请求失败并且 express-graphql 响应为 500。

【讨论】:

以上是关于使用 express-graphql 和 react-apollo 处理错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 express-graphql 和 react-apollo 处理错误

使用 Express-GraphQL 和 React-Apollo 订阅 GraphQL

Express-GraphQL 上的多个过滤器

使用 Express-GraphQL 的 GraphQL 订阅

如何使用 express-graphql 引发多个错误?

Graphql 突变查询不适用于 express-graphql