Правильные нестрочные исключения Javascript
Как-то это не похоже на кульминацию 50-летнего развития языка программирования:
throw "My exception message here";
Какой правильный способ сделать исключения в Javascript, чтобы
-
Они могут быть идентифицированы (instanceof)
-
Они могут нести другую полезную нагрузку, помимо сообщения по умолчанию и трассировки стека
-
Они "подклассы" базы Исключение, так что консоль отладки и такие могут извлекать значимую информацию об исключении
-
Возможные вложенные исключения (преобразование исключения в другое): если вам нужно поймать исключение и повторно создать новую, трассировка стека orignal будет сохранена и может быть осмысленно прочитана средствами отладки
-
Они следуют рекомендациям Javascript
Ответы
Ответ 1
throw new Error("message");
или если вы хотите более конкретно использовать один из Объекты ошибок
Важно, чтобы вы делали реальные ошибки, потому что они содержат трассировку стека. Бросание строки глупо, потому что у нее нет никаких метаданных, прикрепленных к ней.
Вы также можете подклассифицировать ошибки
// for some sensible implementation of extend
// https://gist.github.com/1441105#file_1pd.js
var MyError = extend(Object.create(Error.prototype), {
...
});
Ответ 2
Базовое "исключение" в JavaScript встроено в объект Error
:
throw new Error("My exception message here");
Вы можете определить свои пользовательские исключения как:
function CustomError(message) {
this.message = message;
}
CustomError.prototype = new Error();
CustomError.prototype.constructor = CustomError;
Проверить тип исключения с помощью instanceof
. Существует также удобный список встроенных исключений.
Ответ 3
Вы не можете этого сделать и удовлетворять требованиям к требованиям.
Почему?
Проблема заключается в получении стека. Собственный объект ошибки (теперь NativeError) инициализирует стек при вызове его конструктора. Чтобы получить стек в MyError (ваш подкласс ошибки), вы должны вызвать NativeConstructor внутри конструктора MyError. Итак, ваш класс MyError выглядит примерно так:
function MyError(msg) {
Error.call(this, msg);
}
Но это не работает. Потому что согласно HTML5 spec:
", если вы вызываете Error как функцию, он возвращает новый объект Error".
Вместо конструктора Error, являющегося хорошим и инициализирующим ваш собственный класс ошибок, он создает объект ошибки, для которого вы не используете. Я не нашел способ вызвать конструктор NativeError и инициализировать подкласс MyError.
Не все потеряно.
Если мы расслабляем исходные требования к запросу и забываем о "экземпляре" для проверки класса исключения (так Java все равно), и вместо этого используйте "имя", это можно сделать. Просто объявите MyError как:
function MyError(msg, customArg) {
var e = new Error(msg);
e.name = "MyError";
e.custom = customArg;
return e;
}
Это то, что я делаю. Вместо включения "instanceof" вместо этого включите "имя".
Ответ 4
Вы можете создать объект Error
, вызвав конструктор Error
.
Объект Error
может иметь сообщение и имя. При ловле вы можете проверить определенное имя или создать собственный тип ошибки, наследуя прототип Error
. Это позволяет использовать instanceof
для разных типов ошибок.
// Create a new object, that prototypally inherits from the Error constructor.
function MyError(message) {
this.message = message || "Default Message";
}
MyError.prototype = new Error();
MyError.prototype.constructor = MyError;
try {
throw new MyError();
} catch (e) {
console.log(e.name); // "MyError"
console.log(e.message); // "Default Message"
}
try {
throw new MyError("custom message");
} catch (e) {
console.log(e.name); // "MyError"
console.log(e.message); // "custom message"
}
Пример взято из: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error