使用 ApolloClient 和 Apollo-Server-Express 处理 GraphQL 错误
Posted
技术标签:
【中文标题】使用 ApolloClient 和 Apollo-Server-Express 处理 GraphQL 错误【英文标题】:GraphQL Error Handling with ApolloClient and Apollo-Server-Express 【发布时间】:2018-10-21 17:26:26 【问题描述】:apollo-link-error
的 onError 函数有一个填充的 graphQLErrors 对象,但是当 ApolloClient 抛出一个错误对象时,graphQLErrors
属性包含一个空数组。进一步检查显示 error.networkError.result.errors
中的 graphql 错误消息。
如何正确配置 Apollo 客户端以返回填充的 graphQLErrors
对象?
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
调用 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)
)
控制台结果:
[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] ] ]
库版本:
服务器:
"apollo-server-express": "^1.3.2"
客户:
"apollo-cache-inmemory": "^1.1.12"
"apollo-client": "^2.2.8"
"apollo-link-error": "^1.0.9"
"apollo-link-http": "^1.5.4"
【问题讨论】:
还开了一个github问题:github.com/apollographql/apollo-client/issues/3441 请注意,这种中间件方法在每次请求时都会重新创建 ApolloClient,因此缓存在这里毫无意义。 【参考方案1】:这是设计使然。来自docs:
graphQLErrors:来自 GraphQL 端点的错误数组 networkError:链接执行或服务器响应期间的任何错误, 未作为 GraphQL 结果中的错误字段的一部分提供
换句话说,如果您的查询格式不正确,您请求的字段无效(例如在您的示例中),或者遇到导致状态不是 200 的任何其他问题,则该错误将显示为networkError
财产。另一方面,如果请求返回 200,但响应中的错误数组已填充,则相同的错误将作为 graphQLErrors
的一部分返回。
如果您想查看填充 graphQLErrors
的示例,请正确格式化您的查询,但让您的解析器在调用时立即抛出错误。只要查询没有遇到任何其他问题,您应该会在 graphQLErrors
中看到相同的错误弹出。
【讨论】:
以上是关于使用 ApolloClient 和 Apollo-Server-Express 处理 GraphQL 错误的主要内容,如果未能解决你的问题,请参考以下文章
来自 apollo-boost 的 ApolloClient 试图分配给只读属性
如何使用 ApolloClient 记录 HTTP 请求和响应
NextJS + Apollo:如何在 getServerSideProps 内的 apolloClient.query 上获取多个查询?
ReferenceError:从“apollo-boost”导入 ApolloClient 时未定义要求