Как регистрировать исключения в JavaScript

Как разработчик С#, я использую следующий стиль обработки исключений:

try
{
    throw SomeException("hahahaha!");
}
catch (Exception ex)
{
    Log(ex.ToString());
}

Output
------

SomeNamespace.SomeException: hahahaha!
    at ConsoleApplication1.Main() in ConsoleApplication1\Program.cs:line 27

Это действительно просто, и все же рассказывает мне все, что мне нужно знать о том, что такое исключение и где оно было.

Как достичь эквивалентной вещи в JavaScript, где сам объект исключения может быть просто строкой. Я действительно хочу знать точную строку кода, где произошло исключение, однако следующий код вообще не записывает ничего полезного:

try
{
    var WshShell = new ActiveXObject("WScript.Shell");
    return WshShell.RegRead("HKEY_LOCAL_MACHINE\\Some\\Invalid\\Location");
}
catch (ex)
{
    Log("Caught exception: " + ex);
}

Output
------

Caught exception: [object Error]

РЕДАКТИРОВАТЬ (снова): просто для уточнения, это для внутреннего приложения, которое сильно использует JavaScript. Я после того, как извлечение полезной информации из ошибок JavaScript, которые могут быть пойманы в производственной системе - у меня уже есть механизм ведения журнала, просто хочу получить разумную строку для регистрации.

Ответы

Ответ 1

Вы можете использовать почти таким же образом, например.

try
{
    throw new Error("hahahaha!");
}
catch (e)
{
    alert(e.message)
}

Но если вы хотите получить номер строки и имя файла, где возникла ошибка, я полагаю, что нет решения crossbrowser. Сообщение и имя являются единственными стандартными свойствами объекта Error. В mozilla у вас также есть свойства lineNumber и fileName.

Ответ 2

Вы не указываете, работаете ли вы в браузере или на сервере. Если это первый, существует новый метод console.error и e.stack свойство:

try {
    // do some crazy stuff
} catch (e) {
    console.error(e, e.stack);
}

Пожалуйста, имейте в виду, что ошибка будет работать на Firefox и Chrome, но это не стандартно. Быстрый пример, который будет понижаться до console.log и log e, если нет e.stack:

try {
    // do some crazy stuff
} catch (e) {
    (console.error || console.log).call(console, e.stack || e);
}

Ответ 3

Я знаю, что я опаздываю на вечеринку на 4 года, но все же почувствовал желание добавить свои 2 цента.

Как указывает Эльдар, вы можете использовать e.message, чтобы получить сообщение об исключении. Однако в Chrome, Firefox и IE10 + вы также можете получить трассировку стека, используя e.stack. Трассировка стека будет содержать номер файла и строки исключения.

Итак, чтобы собрать строку с информацией об исключении, вы должны написать что-то вроде этого:

var exmsg = "";
if (e.message) {
    exmsg += e.message;
}
if (e.stack) {
    exmsg += ' | stack: ' + e.stack;
}

Обратите внимание, что вы получите только трассировку стека, если

  • исключение было брошено браузером (например, в ответ на ошибка синтаксиса);
  • объект исключения является объектом Error или имеет объект Error в качестве прототипа.

Поэтому просто бросать строку (throw 'Exception!!') не даст вам трассировки стека.

Чтобы сделать это немного дальше, чтобы поймать все неперехваченные исключения, вы должны использовать обработчик window.onerror(аналогично обработчику .Net Application_Error в global.asax). Недостатком этого было (и в основном все еще), что это не даст вам доступ к фактическому объекту исключения, поэтому вы не сможете получить трассировку стека. Вы получили бы только сообщение, url и номер строки.

Недавно стандарт был расширен, чтобы предоставить вам столбец (отлично подходит для мини файлов) и объект исключения: http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#errorevent

Прямо сейчас (апрель 2014), только Chrome 32 реализует все это. IE10 + предоставляет вам столбец, но не объект исключения. Firefox 28 все еще дает вам сообщение, URL и номер строки. Надеюсь, это скоро улучшится. Я написал об этом для проекта JSNLog: http://jsnlog.com/Documentation/GetStartedLogging/ExceptionLogging

(отказ от ответственности: я являюсь автором JSNLog и jsnlog.com)

Во-вторых, объект .Net Exception поддерживает внутренние исключения. Он также имеет свойство Data, поэтому вы можете присоединить пары значений ключа, например, значения переменных. Я вроде пропустил это в объекте JavaScript Error, поэтому создал собственный объект Exception, также как часть проекта JSNLog. Он находится в файле jsnlog.js в проекте jsnlog.js Github (https://github.com/mperdeck/jsnlog.js).

Описание находится по адресу: http://jsnlog.com/Documentation/JSNLogJs/Exception

Наконец, бесстыдный плагин - проект JSNLog, над которым я работаю, позволяет вставлять регистраторы в ваш JavaScript и автоматически вставляет сообщения журнала в существующий журнал на стороне сервера. Таким образом, чтобы регистрировать исключения JavaScript со своими трассировками стека на сервере, вам нужно только написать:

try {
    ...
} catch (e) {
    JL().fatalException("something went wrong!", e);
}

Ответ 4

Я не уверен, что это кросс-браузер, или если это то, что вы ищете, но я предлагаю вам попробовать:

window.onerror = function (err, file, line) {
    logError('The following error occurred: ' + 
    err + '\nIn file: ' + file + '\nOn line: ' + line);
    return true;
}

Ответ 6

Вы можете использовать инструменты ведения журнала, такие как Yahoo! UI Library - Logger для регистрации ошибок/информационных сообщений.

Ответ 7

Если вы просто хотите увидеть Exception в журнале браузера, я думаю, вам просто нужно выбросить Exception, соответственно, удалить try-catch.

try {
    throw new Error("Exception");
} catch (e) {
    throw e;
}

или

//try {
    throw new Error("Exception");
//} catch (e) {
//    throw e;
//}

чем исключение, автоматически запускается в консоли.