Каков наилучший способ перехвата ВСЕХ исключений, возникающих в JavaScript?
Очевидно, что лучший способ - это попробовать ... поймать. Но с асинхронными обратными вызовами и т. Д. Это может быть сложно.
Я знаю, что браузеры IE и Gecko поддерживают window.onerror, но как насчет Opera и Safari?
Вот несколько тестовых примеров, для которых я хотел бы иметь центральное решение для обработки исключений:
// ErrorHandler-Test1
var test = null;
test.arg = 5;
// ErrorHandler-Test2
throw (new Error("Hello"));
// ErrorHandler-Test3
throw "Hello again";
// ErrorHandler-Test4
throw {
myMessage: "stuff",
customProperty: 5,
anArray: [1, 2, 3]
};
// ErrorHandler-Test5
try {
var test2 = null;
test2.arg = 5;
} catch(e) {
ErrorHandler.handleError(e);
}
// ErrorHandler-Test6
try {
throw (new Error("Goodbye"));
} catch(e) {
ErrorHandler.handleError(e);
}
// ErrorHandler-Test7
try {
throw "Goodbye again";
} catch(e) {
ErrorHandler.handleError(e);
}
// ErrorHandler-Test8
try {
throw {
myMessage: "stuff",
customProperty: 5,
anArray: [1, 2, 3]
};
} catch(e) {
ErrorHandler.handleError(e);
}
Если вы думаете о каких-либо других тестовых примерах, укажите их. В некоторых из этих случаев упоминается метод ErrorHandler.handleError. Это всего лишь рекомендуемый совет при использовании try ... catch.
javascript
exception
harley.333
источник
источник
window.onerror
отсутствие ошибок было проблемой с 2003 года , но похоже, что она наконец решается . Конечно, Opera останется упрямой.Ответы:
Если вы используете библиотеку, такую как jQuery, для назначения всех ваших обработчиков событий, вы можете использовать комбинацию
window.onerror
и упаковку кода обработчика событий jQuery и готовую функцию с функцией обработки ошибок (см .: Отслеживание ошибок JavaScript: почему window.onerror недостаточно ).window.onerror
: ловит все ошибки в IE (и большинство ошибок в Firefox), но ничего не делает в Safari и Opera.источник
onerror
подход к работе в Safari + Chrome и, похоже, работает правильно.WebKit (Safari, Chrome и т. Д.) Теперь, похоже, поддерживает
onerror
.Исходный пост: Насколько я знаю, WebKit / Safari не поддерживает это
onerror
событие. Это чертовски обидно.источник
На самом деле подход jquery не так уж и плох. Видеть:
http://docs.jquery.com/Events/error#fn
и:
$(window).error(function(msg, url, line){ $.post("js_error_log.php", { msg: msg, url: url, line: line }); });
источник
Поймайте все исключения своим собственным обработчиком исключений и используйте instanceof.
$("inuput").live({ click : function (event) { try { if (somethingGoesWrong) { throw new MyException(); } } catch (Exception) { new MyExceptionHandler(Exception); } } }); function MyExceptionHandler(Exception) { if (Exception instanceof TypeError || Exception instanceof ReferenceError || Exception instanceof RangeError || Exception instanceof SyntaxError || Exception instanceof URIError ) { throw Exception; // native error } else { // handle exception } }
MyExcetpionHandler выдаст собственную ошибку, поскольку нет блока try-catch.
Посетите http://www.nczonline.net/blog/2009/03/10/the-art-of-throwing-javascript-errors-part-2/.
источник
try-catch
не всегда лучшее решение. Например, в Chrome 7.0 вы теряете красивую трассировку стека в окне консоли. Повторное отображение исключения не помогает. Я не знаю ни одного решения, которое сохраняет следы стека и позволяет вам реагировать на исключение.источник
Немного поработав, можно получить достаточно полные трассировки стека во всех браузерах.
Современные Chrome и Opera (то есть все, что основано на движке рендеринга Blink) полностью поддерживают черновую спецификацию HTML 5 для ErrorEvent и
window.onerror
. В обоих этих браузерах вы можете либо использоватьwindow.onerror
, либо (что удивительно!) Правильно привязать к событию error:// Only Chrome & Opera pass the error object. window.onerror = function (message, file, line, col, error) { console.log(message, "from", error.stack); // You can send data to your server // sendData(data); }; // Only Chrome & Opera have an error attribute on the event. window.addEventListener("error", function (e) { console.log(e.error.message, "from", e.error.stack); // You can send data to your server // sendData(data); })
К сожалению, Firefox, Safari и IE все еще существуют, и мы тоже должны их поддерживать. Поскольку трассировка стека недоступна,
window.onerror
нам нужно проделать еще немного работы.Оказывается, единственное, что мы можем сделать, чтобы получить трассировку стека ошибок, - это обернуть весь наш код в
try{ }catch(e){ }
блок, а затем посмотреть на e.stack. Мы можем несколько упростить процесс с помощью функции под названием wrap, которая принимает функцию и возвращает новую функцию с хорошей обработкой ошибок.function wrap(func) { // Ensure we only wrap the function once. if (!func._wrapped) { func._wrapped = function () { try{ func.apply(this, arguments); } catch(e) { console.log(e.message, "from", e.stack); // You can send data to your server // sendData(data); throw e; } } } return func._wrapped; };
Это работает. Любая функция, которую вы переносите вручную, будет хорошо обрабатывать ошибки.
Вы можете отправить данные с помощью тега изображения следующим образом
function sendData(data) { var img = newImage(), src = http://yourserver.com/jserror + '&data=' + encodeURIComponent(JSON.stringify(data)); img.crossOrigin = 'anonymous'; img.onload = function success() { console.log('success', data); }; img.onerror = img.onabort = function failure() { console.error('failure', data); }; img.src = src; }
Однако вам нужно сделать бэкэнд для сбора данных и внешний интерфейс для визуализации данных.
В Atatus мы работаем над решением этой проблемы. Atatus обеспечивает не только отслеживание ошибок, но и реальный мониторинг пользователей.
Отказ от ответственности: я веб-разработчик в Atatus.
источник
Это правда, что в современных браузерах перехват window.onerror для ошибок, которые всплывают наверх, вместе с добавлением обработчиков событий jQuery для ошибок Ajax, перехватит практически все объекты Error, добавленные в код вашего клиента. Если вы вручную настраиваете обработчик для window.onerror, в современных браузерах это делается с помощью
window.addEventListener('error', callback)
, а в IE8 / 9 вам нужно вызватьwindow.attachEvent('onerror', callback)
.Обратите внимание, что затем вам следует рассмотреть среду, в которой обрабатываются эти ошибки, и причину этого. Одно дело - поймать как можно больше ошибок с их трассировками стека, но появление современных инструментов разработки F12 решает этот вариант использования при локальной реализации и отладке. Точки останова и т. Д. Предоставят вам больше данных, чем доступно из обработчиков, особенно для ошибок, вызванных сторонними библиотеками, которые были загружены из запросов CORS. Вам необходимо предпринять дополнительные шаги, чтобы указать браузеру предоставить эти данные.
Ключевой проблемой является предоставление этих данных в производственной среде, так как ваши пользователи гарантированно будут запускать гораздо более широкий спектр браузеров и версий, чем вы можете протестировать, и ваш сайт / приложение выйдет из строя неожиданными способами, независимо от того, сколько QA вы бросите. Это.
Чтобы справиться с этим, вам нужен трекер производственных ошибок, который улавливает каждую ошибку, возникшую в браузерах вашего пользователя, когда они используют ваш код, и отправляет их в конечную точку, где вы можете просматривать данные и использовать для исправления ошибок по мере их появления. . В Raygun (отказ от ответственности: я работаю в Raygun) мы приложили кучу усилий, чтобы обеспечить отличный опыт для этого, так как есть много подводных камней и проблем, которые следует учитывать при наивной реализации.
Например, есть вероятность, что вы будете объединять и минимизировать свои ресурсы JS, а это означает, что ошибки, возникающие из минимизированного кода, будут иметь следы нежелательного стека с искаженными именами переменных. Для этого вам понадобится инструмент сборки для генерации исходных карт (мы рекомендуем UglifyJS2 для этой части конвейера) и ваш трекер ошибок, чтобы принимать и обрабатывать их, превращая искаженные трассировки стека обратно в удобочитаемые. Raygun делает все это из коробки и включает конечную точку API для приема исходных карт в том виде, в каком они создаются в процессе сборки. Это ключевой момент, поскольку они не должны быть общедоступными, иначе любой может уничтожить ваш код, отрицая его назначение.
Raygun4js клиентская библиотека также поставляется с
window.onerror
для современных и устаревших браузеров, а также JQuery перехватывает вне коробки, так чтобы установить это вам нужно только добавить:<script type="text/javascript" src="//cdn.raygun.io/raygun4js/raygun.min.js" </script> <script> Raygun.init('yourApiKey').attach(); </script>
Также имеется множество встроенных функций, включая возможность изменять полезную нагрузку ошибки перед ее отправкой, добавлять теги и пользовательские данные, метаданные о пользователе, который увидел ошибку. Это также облегчает получение хороших трассировок стека из вышеупомянутых сторонних сценариев CORS, которые решают ужасную «ошибку сценария» (которая не содержит сообщений об ошибках и трассировки стека).
Более важная проблема заключается в том, что из-за огромной аудитории в Интернете ваш сайт будет генерировать тысячи повторяющихся экземпляров каждой ошибки. Служба отслеживания ошибок, такая как Raygun , умеет объединять их в группы ошибок, чтобы вы не утонули в потоке уведомлений, и позволяет вам видеть каждую фактическую ошибку, готовую к исправлению.
источник
Я также искал обработку ошибок, трассировку стека и регистрацию действий пользователя, это то, что я нашел, надеюсь, это также поможет вам https://github.com/jefferyto/glitchjs
источник