Правильные нестроковые исключения Javascript - PullRequest
29 голосов
/ 29 января 2012

Почему-то это не похоже на кульминацию 50-летнего развития языка программирования:

  throw "My exception message here";

Как правильно делать исключения в Javascript, чтобы

  • Их можно идентифицировать (instanceof)

  • Они могут нести другую полезную нагрузку, кроме сообщения по умолчанию и трассировки стека

  • Они «подкласс» базового исключения, так что отладочная консоль и тому подобное могут извлечь значимую информацию об исключении

  • Возможные вложенные исключения (преобразование исключения в другое): если вам нужно перехватить исключение и перебросить новое, трассировка оригинального стека будет сохранена и может быть осмысленно прочитана средствами отладки

  • Они следуют лучшим практикам Javascript

Ответы [ 4 ]

25 голосов
/ 29 января 2012

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), {
   ...
});
9 голосов
/ 29 января 2012

Базовым «исключением» в 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 голосов
/ 17 июня 2013

Вы не можете сделать это, и удовлетворить требования вопроса.

Почему?

Проблема в получении стека. Собственный объект ошибки (с этого момента NativeError) инициализирует стек при вызове его конструктора. Чтобы получить стек в MyError (ваш подкласс ошибок), вы должны вызвать NativeConstructor внутри конструктора MyError. Итак, ваш класс MyError выглядит примерно так:

function MyError(msg) {
    Error.call(this, msg);
}

Но это не работает. Потому что согласно HTML5 spec:

«если вы вызываете Error как функцию, она возвращает новый объект Error».

Вместо того, чтобы конструктор Error был красивым и инициализировал ваш собственный класс ошибок, он создает объект ошибки, который вам не нужен. Я не нашел способ вызвать конструктор NativeError и заставить его инициализировать подкласс MyError.

Не все потеряно.

Если мы ослабим требования исходного вопроса и забудем об «instanceof», чтобы протестировать класс исключений (так или иначе, Java), и вместо этого будем использовать «name», это можно сделать. Просто объявите MyError как:

function MyError(msg, customArg) {
    var e = new Error(msg);
    e.name = "MyError";
    e.custom = customArg;
    return e;
}

Это то, что я делаю. Вместо включения «instanceof» вместо этого включите «name».

2 голосов
/ 29 января 2012

Вы можете создать объект 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...