简体   繁体   English

使用ApolloClient和Apollo-Server-Express进行GraphQL错误处理

[英]GraphQL Error Handling with ApolloClient and Apollo-Server-Express

The onError function from apollo-link-error has a populated graphQLErrors Object, but when ApolloClient throws an error object, the graphQLErrors property contains an empty array. 来自apollo-link-error的onError函数具有一个填充的graphQLErrors对象,但是当ApolloClient抛出一个错误对象时, graphQLErrors属性将包含一个空数组。 Further inspection reveals the graphql error message in error.networkError.result.errors . 进一步的检查揭示了graphql错误消息error.networkError.result.errors

How can one properly configure Apollo Client to return a populated graphQLErrors object? 如何正确配置Apollo客户端以返回填充的graphQLErrors对象?

Apollo Client Setup: Apollo客户端安装程序:

const {ApolloClient} = require('apollo-client')
const { ApolloLink } = require('apollo-link')

const {HttpLink} = require('apollo-link-http')
const {onError} = require('apollo-link-error')
const {InMemoryCache} = require('apollo-cache-inmemory')

const errorLink = onError(({ graphQLErrors, networkError }) => {
  if (graphQLErrors) {
    graphQLErrors.map(({ message, locations, path }) =>
      console.log(
        `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
      ),
    )
  }

  if (networkError) console.log(`[Network error]: ${networkError}`)
})

const middleware = (req, ignored_res, next) => {
  const client = new ApolloClient({
    link: ApolloLink.from([errorLink, new HttpLink({ uri:'http://somegraphqlserver.com', fetch: require('node-fetch') })]),
    cache: new InMemoryCache(),
  })

  req.GQLClient = client

  return next()
}

module.exports = middleware

Calling apollo-server-express: 调用apollo-server-express:

req.GQLClient
    .query({
      query: SOME_MALFORMED_QUERY,
    })
    .then((data) => {...})
    .catch((error) => {
      console.log('rawError', error)
      console.log('error.networkError.result.errors', error.networkError.result.errors)
      return next(error)
    })

Console Results: 控制台结果:

[GraphQL error]: Message: Cannot query field "blah" on type "CustomerList"., Location: [object Object], Path: undefined
[Network error]: Error: Response not successful: Received status code 400


 rawError { Error: Network error: Response not successful: Received status code 400
   at new ApolloError (/.../node_modules/apollo-client/bundle.umd.js:121:28)
   at /.../node_modules/apollo-client/bundle.umd.js:1187:41
   at /.../node_modules/apollo-client/bundle.umd.js:1620:17
   at Array.forEach (<anonymous>)
   at /.../node_modules/apollo-client/bundle.umd.js:1619:18
   at Map.forEach (<anonymous>)
   at QueryManager.broadcastQueries (/.../node_modules/apollo-client/bundle.umd.js:1614:22)
   at /.../node_modules/apollo-client/bundle.umd.js:1114:31
   at process._tickCallback (internal/process/next_tick.js:178:7)
 graphQLErrors: [],
 networkError: 
  { Error: Response not successful: Received status code 400
   at throwServerError (/.../node_modules/apollo-link-http-common/lib/bundle.umd.js:33:21)
   at /.../node_modules/apollo-link-http-common/lib/bundle.umd.js:58:17
   at process._tickCallback (internal/process/next_tick.js:178:7)
    response: 
     Response {
       size: 0,
       timeout: 0,
       [Symbol(Body internals)]: [Object],
       [Symbol(Response internals)]: [Object] },
    statusCode: 400,
    result: { errors: [Array] } },
 message: 'Network error: Response not successful: Received status code 400',
 extraInfo: undefined }


error.networkError.result.errors [ { message: 'Cannot query field "blah" on type "CustomerList".',
   locations: [ [Object] ] } ]

library versions: 库版本:

Server: 服务器:

"apollo-server-express": "^1.3.2"

Client: 客户:

"apollo-cache-inmemory": "^1.1.12"
"apollo-client": "^2.2.8"
"apollo-link-error": "^1.0.9"
"apollo-link-http": "^1.5.4"

This is by design. 这是设计使然。 From the docs : 文档

  • graphQLErrors: An array of errors from the GraphQL endpoint graphQLErrors:来自GraphQL端点的错误数组
  • networkError: Any error during the link execution or server response, that wasn't delivered as part of the errors field in the GraphQL result networkError:链接执行或服务器响应期间出现的任何错误,但未作为GraphQL结果中的error字段的一部分提供

In other words, if your query is malformed, you request a field that isn't valid (like in your example), or hit any other issue that results in status other than 200, the error will appear as part of the networkError property. 换句话说,如果查询格式错误,您请求的字段无效(例如您的示例中),或者遇到任何其他导致状态不为200的问题,则该错误将显示为networkError属性的一部分。 On the other hand, if the request returns a 200, but the errors array inside the response is populated, those same errors will be returned as part of graphQLErrors . 另一方面,如果请求返回200,但填充了响应内部的errors数组,则那些相同的错误将作为graphQLErrors一部分返回。

If you want to see an example of graphQLErrors being populated, format your query correctly but have one of your resolvers throw an error as soon as it's called. 如果要查看正在填充的graphQLErrors的示例,请正确格式化查询,但是让其中一个解析器在调用后立即引发错误。 As long as the query doesn't hit any other issues, you should see the same error pop up inside graphQLErrors . 只要查询没有遇到其他问题,您都应该在graphQLErrors内部看到相同的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM