Пользовательский объект ошибки с сервером Apollo

#javascript #ecmascript-6 #graphql #apollo-server

#javascript #ecmascript-6 #graphql #apollo-сервер

Вопрос:

Я пытаюсь использовать пользовательскую ошибку с apollo-server, и кажется, что моя пользовательская ошибка имеет свойство ( code ), которое недоступно изнутри formatError .

 import ExtendableError from 'es6-error'

export default class MyError extends ExtendableError {
  constructor(args) {
    let code = Object.keys(args)[0]
    let message = Object.values(args)[0]
    super(message)
    this.code = code
  }
}
  

У меня простой обработчик ошибок работает примерно так:

 let INVALIDREQUEST = 'invalid request'
let e = new MyError({INVALIDREQUEST})
console.log(e.code) // => "INVALIDREQUEST"
  

У меня возникли проблемы, потому что, когда я регистрируюсь error.code изнутри formatError , он недоступен.

 formatError: function (error) {
  console.log(error.code) // => undefined
  return error
}
  

Как я могу распространять пользовательские свойства (например code ) error изнутри formatError ?

Ответ №1:

Поскольку сервер Apollo использует GraphQL.js мы можем найти решение, углубившись в него: https://github.com/graphql/graphql-js/blob/44f315d1ff72ab32b794937fd11a7f8e792fd873/src/error/GraphQLError.js#L66-L69

По сути, GraphQL.js эталонная реализация улавливает любые ошибки в ваших распознавателях и доставляет их в formatError функцию, но она помещает их в специальный объект ошибки, специфичный для GraphQL, с такими свойствами, как path , positions и source .

Вы можете найти исходную ошибку, которую вы выдали из преобразователя, в originalError поле error объекта в formatError , вот так:

 formatError: function (error) {
  console.log(error.originalError.code)
  return error
}
  

Комментарии:

1. почему журнал узла отличается от graphiql? в graphiql я могу видеть состояния при добавлении в formaterror: error.state = error.originalError; но в консоли узла я вижу только: путь GraphQLError ( .. at locatedError ..), позиции и источник. могу ли я увидеть в консоли на узле мое свойство состояния?

Ответ №2:

С помощью Apollo вы можете легко мультиплексировать массив ошибок в ответе graphql как для ошибок graphql, так и для пользовательских ошибок, которые можно считывать с помощью этого пакета:

https://github.com/thebigredgeek/apollo-errors

Ответ №3:

Обычно этого достаточно. Вы можете определить код ошибки (2 параметра), сообщение об ошибке и любой пользовательский объект в расширениях (3 параметра)

      throw new ApolloError('User already exist',
                           'DUPLICATE',
                           { 'session': session })
  

Комментарии:

1. Выбрасывание ЛЮБОГО ApolloeError или его подкласса всегда будет удалять сообщение и вставлять Unexpected error value: { extensions: { code: <your code> }} вместо того, чтобы фактически просто передавать ошибку или представлять ошибку как выброшенную. Сообщение всегда опускается, что сводит на нет весь процесс использования типа ApolloError, если formatError всегда уничтожает то, что вы на самом деле хотите выбросить.