Я пытаюсь расширить Error с помощью ES6 и Babel. Не получается.
class MyError extends Error {
constructor(m) {
super(m);
}
}
var error = new Error("ll");
var myerror = new MyError("ll");
console.log(error.message) //shows up correctly
console.log(myerror.message) //shows empty string
Объект Error никогда не получает правильный набор сообщений.
Теперь я видел несколько решений на SO ( например, здесь ), но все они кажутся очень не-ES6-y. Как это сделать красивым способом на ES6? (Это работает в Вавилоне)
javascript
ecmascript-6
babeljs
transpiler
Карел Билек
источник
источник
Ответы:
Основываясь на ответе Карела Билека, я бы внес небольшое изменение в
constructor
:Это будет печататься
MyError
в стеке, а не в общемError
.Он также добавит сообщение об ошибке в трассировку стека, которого не было в примере Карела.
Он также будет использоваться,
captureStackTrace
если он доступен.В Babel 6 вам понадобится transform-builtin-extend ( npm ), чтобы это работало.
источник
if (typeof Error.captureStackTrace === 'function') { Error.captureStackTrace(this, this.constructor.name) } else { this.stack = (new Error(message)).stack; }
. Я бы сказал, что лучше использовать эту функцию, если она доступна, поскольку она предоставляет более «родной» стек вызовов и печатает имя объекта ошибки. Конечно, если вы используете это исключительно на стороне сервера (узел), то это тоже не проблема.this.stack = (new Error(message)).stack
выбираете имя класса ошибки, то получаете это ... но на практике это, вероятно, не имеет большого значения.new MyError('foo') instanceof MyError === false
extendable-error-class
npmjs.com/package/extendable-error-class, что удобно, чтобы избежать зависимости от babel-plugin-transform-builtin-extendthis.message = message;
является избыточным сsuper(message);
Объединив этот ответ , этот ответ и этот код , я создал этот небольшой «вспомогательный» класс, который, кажется, работает нормально.
Попробуй в REPL
источник
this.stack = (new Error(message)).stack;
- в противном случае сообщение отсутствует в stacktracemessage
в конструктор стека ошибок, чтобы он отображал правильное сообщение вверху стека при вызове:this.stack = (new Error(message)).stack;
myerror.name
теперь возвращает "Ошибка". Не уверен, связано ли это с более поздними версиями babel. См. Ответ @sukima нижеЧтобы наконец положить этому конец. В Babel 6 явно указано, что разработчики не поддерживают расширение из встроенных. Хотя этот трюк не поможет с такими вещами, как
Map
,Set
и т.д., он работаетError
. Это важно, поскольку одна из основных идей языка, который может генерировать исключение, - разрешить настраиваемые ошибки. Это вдвойне важно, поскольку промисы становятся более полезными, поскольку они предназначены для отклонения ошибок .Печальная правда в том, что в ES2015 вам все еще нужно делать это по-старому.
Пример в Babel REPL
Пользовательский шаблон ошибки
С другой стороны, для Babel 6 есть плагин, позволяющий это сделать.
https://www.npmjs.com/package/babel-plugin-transform-builtin-extend
Обновление: (по состоянию на 29.09.2016). После некоторого тестирования выяснилось, что babel.io не учитывает должным образом все утверждения (за счет расширенной пользовательской ошибки). Но в Ember.JS ошибка расширения работает должным образом: https://ember-twiddle.com/d88555a6f408174df0a4c8e0fd6b27ce
источник
Error.toString()
. Необходимость делать специальные обручи и повороты для достижения этой цели означает, что большинство разработчиков будут избегать этого и прибегать к плохим методам, таким как бросание струн вместо ошибок. Или сделать свою собственную карту как объекты. Почему нужно сдерживать такие методы ООП?Изменить : критические изменения в Typescript 2.1
Редактирование оригинального ответа Ли Бенсона немного работает для меня. Это также добавляет к экземпляру
stack
дополнительные методыExtendableError
класса.источник
Object.setPrototypeOf
вMyError
конструкторе также. stackoverflow.com/a/41102306/186334 github.com/Microsoft/TypeScript-wiki/blob/master/…С последними изменениями в babel 6 я обнаружил, что transform-builtin-extend больше не работает. В итоге я использовал этот смешанный подход:
и
В результате все эти тесты проходят:
источник
квотирование
Хотя приведенные выше коды не могут выводить трассировку стека, если только
this.stack = (new Error()).stack;
илиError.captureStackTrace(this, this.constructor.name);
не вызывается в Babel . ИМО, это может быть одна проблема.Фактически, трассировка стека может выводиться в этих фрагментах кода
Chrome console
иNode.js v4.2.1
с их помощью.Выход
Chrome console
.Выход из
Node.js
источник
В дополнение к ответу @zangw вы можете определить свои ошибки следующим образом:
который выдаст правильное имя, сообщение и трассировку стека:
источник
new MyError('foo') instanceof MyError === false
.Node.js v7.7.3
.Этот
class MyError extends Error {…}
синтаксис правильный.Обратите внимание, что у транспиляторов все еще есть проблемы с наследованием от встроенных объектов. В твоем случае,
вроде решает проблему.
источник
Error.call()
возвращает мне новый экземпляр ошибки.Учитывая это, принятый ответ больше не работает, вы всегда можете использовать фабрику в качестве альтернативы ( ответ ):
источник
Я предпочитаю более строгий синтаксис, чем описано выше. Дополнительные методы при типе ошибки помогут вам создать красивое
console.log
или что-то еще.Чтобы проверить этот код, вы можете запустить нечто подобное:
Расширение
CustomError
типа приветствуется. К расширенному типу можно добавить определенные функции или заменить существующие. Например.источник
Как упоминает @sukima, вы не можете расширять собственный JS. На вопрос ОП нельзя ответить.
Как и в ответе Melbourne2991 , я скорее использовал фабрику, но следовал рекомендациям MDN для типов ошибок клиентов .
источник
Это работает для меня:
источник
Я не использую Babel, но в обычном ES6, мне кажется, что следующее работает нормально:
Тестирование из REPL:
Как видите, стек содержит как имя ошибки, так и сообщение. Я не уверен, что мне что-то не хватает, но все остальные ответы, кажется, слишком усложняют ситуацию.
источник
Я немного улучшил решение @Lee Benson следующим образом:
extendableError.js
пример ошибки
Затем вы можете группировать ошибки, имея спецификаторы параметров, чтобы решить, что делать по-другому в некоторых конкретных ситуациях вашего приложения.
источник