#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, так и для пользовательских ошибок, которые можно считывать с помощью этого пакета:
Ответ №3:
Обычно этого достаточно. Вы можете определить код ошибки (2 параметра), сообщение об ошибке и любой пользовательский объект в расширениях (3 параметра)
throw new ApolloError('User already exist',
'DUPLICATE',
{ 'session': session })
Комментарии:
1. Выбрасывание ЛЮБОГО
ApolloeError
или его подкласса всегда будет удалять сообщение и вставлятьUnexpected error value: { extensions: { code: <your code> }}
вместо того, чтобы фактически просто передавать ошибку или представлять ошибку как выброшенную. Сообщение всегда опускается, что сводит на нет весь процесс использования типа ApolloError, еслиformatError
всегда уничтожает то, что вы на самом деле хотите выбросить.