window.onerror не запускается в Firefox - PullRequest
17 голосов
/ 17 июня 2009

Я пытаюсь создать инфраструктуру регистрации ошибок 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, но функция my window.onerror по-прежнему не вызывается.

Есть мысли о том, как переопределить то, что делает Firefox?

Ответы [ 3 ]

23 голосов
/ 17 июня 2009

Следующие тестируются и работают в 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, и в результате может привести к непоследовательному поведению от браузера к браузеру, поэтому я удалил его.

EDIT:

Это полный тестовый пример для демонстрации события 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, удалить свои локальные профили (информация о том, как найти ваш профиль, доступна здесь ), переустановить последнюю версию и протестировать заново.

7 голосов
/ 17 июня 2009

Не забудьте вернуть true из любого пользовательского обработчика window.onerror, иначе Firefox все равно его обработает.

2 голосов
/ 26 июня 2009

Похоже, что в jQuery 1.3.x есть открытая ошибка (# 3982). Событие jQuery.error получает неверные аргументы . Последнее обновление было сделано 2 месяца назад с комментарием:

Учитывая, насколько сумасшедшим является событие ошибки, и как часто это используется, я согласен что проще всего убрать поддержку для этого. Я добавил примечание к документам уже, так как это все равно не сработало.

Полагаю, я бы сам установил window.onerror, аналогично тому, что написал Грант. Также FireFox: addEventListener Vs. window.onerror упоминает, что "element.addEventListener", вызывая ошибку, не активирует "window.onerror" .

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