Обработка ошибок GraphQL с помощью ApolloClient и Apollo-Server-Express - PullRequest
0 голосов
/ 11 мая 2018

Функция onError из apollo-link-error имеет заполненный объект graphQLErrors, но когда ApolloClient генерирует объект ошибки, свойство graphQLErrors содержит пустой массив. Дальнейшая проверка выдает сообщение об ошибке graphql в error.networkError.result.errors.

Как правильно настроить клиент 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"

1 Ответ

0 голосов
/ 11 мая 2018

Это по замыслу.Из документов :

  • graphQLErrors: массив ошибок от конечной точки GraphQL
  • networkError: любая ошибка во время выполнения ссылки или ответа сервера,это не было доставлено как часть поля ошибок в результате GraphQL

Другими словами, если ваш запрос искажен, вы запрашиваете поле, которое недопустимо (как в вашемпример), или если возникла другая проблема, которая приводит к состоянию, отличному от 200, ошибка будет отображаться как часть свойства networkError.С другой стороны, если запрос возвращает 200, но массив ответа внутри ответа заполнен, те же самые ошибки будут возвращены как часть graphQLErrors.

Если вы хотите увидеть пример graphQLErrors Заполните, отформатируйте ваш запрос правильно, но пусть один из ваших распознавателей выдаст ошибку, как только она будет вызвана.Пока запрос не затрагивает другие проблемы, вы должны увидеть ту же ошибку, всплывающую внутри graphQLErrors.

...