window.onerror не запускается в Firefox
Я пытаюсь создать инфраструктуру регистрации ошибок JavaScript.
Я пытаюсь установить window.onerror
быть моим обработчиком ошибок. Он работает в IE 6, но когда я запускаю его в Firefox, он сталкивается с некоторыми конфликтующими onerror
метод.
var debug = true;
MySite.Namespace.ErrorLogger.prototype = {
//My error handling function.
//If it's not in debug mode, I should get an alert telling me the error.
//If it is, give a different alert, and let the browser handle the error.
onError: function(msg, url, lineNo) {
alert('onError: ' + msg);
if (!debug) {
alert('not debug mode');
return true;
}
else {
alert(msg);
return false;
}
}
}
//Document ready handler (jQuery shorthand)
$(function() {
log = $create(MySite.Namespace.ErrorLogger);
window.onerror = log.onError;
$(window).error(function(msg, url, line) {
log.onError(msg, url, line);
});
});
Если я использую setTimeout("eval('a')", 1);
где 'a
'- неопределенная переменная, мой обработчик ошибок - это то, что сработало (это работает). Однако мой регистратор ошибок должен отлавливать все ошибки, возникающие у клиентов, обращающихся к сайту, а не только неправильный код в одном месте.
Код находится на странице.js, которая вызывается с базовой страницы (C#) веб-сайта. На сайте также используется jQuery, поэтому у меня есть функция, которая переопределяет функцию привязки jQuery, и эта функция отлично работает как в Firefox 3, так и в IE 6.
Я знаю, что Firefox видит ошибку, потому что она появляется и в консоли ошибок, и в Firebug, но мой window.onerror
функция до сих пор не вызывается.
Любые мысли о том, как отменить то, что делает Firefox?
3 ответа
Следующее протестировано и работает в IE 6 и Firefox 3.0.11:
<html>
<head>
<title>Title</title>
</head>
<body>
<script type="text/javascript">
window.onerror = function (msg, url, num) {
alert(msg + ';' + url + ';' + num);
return true;
}
</script>
<div>
...content...
</div>
<script type="text/javascript">
blah;
</script>
</body>
</html>
Если какая-то другая библиотека JavaScript, которую вы загружаете, также присоединяется к window.onerror
вы можете сделать это:
<script type="text/javascript">
function addHandler(obj, evnt, handler) {
if (obj.addEventListener) {
obj.addEventListener(evnt.replace(/^on/, ''), handler, false);
// Note: attachEvent fires handlers in the reverse order they
// were attached. This is the opposite of what addEventListener
// and manual attachment do.
//} else if (obj.attachEvent) {
// obj.attachEvent(evnt, handler);
} else {
if (obj[evnt]) {
var origHandler = obj[evnt];
obj[evnt] = function(evt) {
origHandler(evt);
handler(evt);
}
} else {
obj[evnt] = function(evt) {
handler(evt);
}
}
}
}
addHandler(window, 'onerror', function (msg, url, num) {
alert(msg + ';' + url + ';' + num);
return true;
});
addHandler(window, 'onerror', function (msg, url, num) {
alert('and again ' + msg + ';' + url + ';' + num);
return true;
});
</script>
Выше можно прикрепить как можно больше onerror
обработчики, как вы хотите. Если уже есть существующий кастом onerror
обработчик это вызовет тот, а затем ваш.
Обратите внимание, что addHandler()
может использоваться для привязки нескольких обработчиков к любому событию:
addHandler(window, 'onload', function () { alert('one'); });
addHandler(window, 'onload', function () { alert('two'); });
addHandler(window, 'onload', function () { alert('three'); });
Этот код является новым и несколько экспериментальным. Я не уверен на 100%, что addEventListener делает именно то, что делает ручное вложение, и, как прокомментировано, attachEvent запускает обработчики в обратном порядке, в котором они были присоединены (так что вы увидите "три, два, один" в примере выше). Хотя это не обязательно "неправильно" или "неправильно", это противоположно тому, что другой код в addHandler
и, как следствие, может привести к непоследовательному поведению от браузера к браузеру, поэтому я удалил его.
РЕДАКТИРОВАТЬ:
Это полный тестовый пример для демонстрации события onerror:
<html>
<head>
<title>Title</title>
</head>
<body>
<script type="text/javascript">
function addHandler(obj, evnt, handler) {
if (obj.addEventListener) {
obj.addEventListener(evnt.replace(/^on/, ''), handler, false);
} else {
if (obj[evnt]) {
var origHandler = obj[evnt];
obj[evnt] = function(evt) {
origHandler(evt);
handler(evt);
}
} else {
obj[evnt] = function(evt) {
handler(evt);
}
}
}
}
addHandler(window, 'onerror', function (msg, url, num) {
alert(msg + ';' + url + ';' + num);
return true;
});
</script>
<div>
...content...
</div>
<script type="text/javascript">
blah;
</script>
</body>
</html>
Когда приведенный выше код помещается в test.htm и загружается в Internet Explorer с локальных идентификаторов, вы должны увидеть диалоговое окно с надписью 'blah' is undefined;undefined;undefined
,
Когда приведенный выше код помещается в test.htm и загружается в Firefox 3.0.11 (и последние версии 3.5 на момент редактирования - Gecko/20090616) с локального диска, вы должны увидеть диалоговое окно с надписью [object Event];undefined;undefined
, Если этого не происходит, значит, ваша копия Firefox неправильно настроена или повреждена. Все, что я могу предложить, - это удалить Firefox, удалить свои локальные профили (информация о том, как найти ваш профиль, доступна здесь), переустановить последнюю версию и протестировать снова.
Не забудьте вернуть true из любого пользовательского обработчика window.onerror, иначе firefox все равно его обработает.
Похоже, что в jQuery 1.3.x есть открытая ошибка (#3982) - событие jQuery.error получает неверные аргументы. Последнее обновление было сделано 2 месяца назад с комментарием:
Учитывая, насколько сумасшедшим является событие ошибки и как часто оно используется, я согласен, что его проще всего удалить. Я уже добавил примечание к документам, так как оно все равно не работает.
Думаю, я бы сам установил window.onerror, аналогично тому, что написал Грант. Кроме того, FireFox: addEventListener Vs. window.onerror упоминает, что "element.addEventListener", вызывая ошибку, не активирует "window.onerror".