Подтвердить что ты не робот

Как мы можем слушать ошибки, которые не запускают window.onerror?

https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers.onerror:

Обратите внимание, что некоторые/многие события ошибки не вызывают window.onerror, вы должны их специально прослушать.

  • Не могли бы вы привести несколько примеров ошибок, которые не запускают window.onerror? Я знаю, что SyntaxError является одним из них.
  • Не могли бы вы привести небольшой пример кода, чтобы показать, как мы можем слушать такие ошибки? Можем ли мы также слушать SyntaxError?
4b9b3361

Ответ 1

window.onerror запускается, будь то синтаксис или ошибка времени выполнения. Эта страница из quirksmode содержит списки событий, которые она будет делать и не будет ловить.

Не могли бы вы представить небольшой пример кода, чтобы показать, как мы можем слушать такие ошибки? Можем ли мы также прослушать SyntaxError?

Для небольшого примера кода, чтобы показать, как мы можем слушать такие ошибки:

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
       <script  type="text/javascript">
           window.onerror = function (errorMsg, url, lineNumber) {
               alert(errorMsg + lineNumber);
               // alert("This is a stack trace! Wow! --> %s", error.stack);
            };
       </script>
    </head>

    <body>
     <script type="text/javascript">
        //var x=document.getElementById("demo").value; //uncomment and run to see
        document.write('careless to close the parentheses?'; // ')' is not given
      </script>
    </body>
</html>

В этом примере в вашем браузере появится предупреждающее сообщение, подобное этому:

Ошибка JavaScript: SyntaxError: отсутствует) после списка аргументов в строке 26 для page_url

В приведенном выше примере: window.onerror = function(message, url, linenumber), аргументы:

  • message: сообщение об ошибке (DOMString)
  • url: URL-адрес файла, содержащего ошибку (DOMString)
  • linenumber: номер строки, в которой произошла ошибка (unsigned long)

Если вы запустите тот же пример, поместив var x=document.getElementById("demo").value; вместо кода с синтаксической ошибкой (как я показал в примере), он также будет пойман функцией window.onerror() и отобразит предупреждающее сообщение, подобное это:

Ошибка JavaScript: TypeError: document.getElementById(...) имеет значение null строка 25 для page_url

window.onerror действует как глобальный блок try/catch, позволяя вам грациозно обрабатывать (даже с протоколированием сервера). Неотображаемые исключения вы didnt ожидайте увидеть:

  • исключаемые исключения

    • throw "some messages"
    • call_something_undefined();
    • cross_origin_iframe.contentWindow.document;, исключение безопасности
  • некоторая ошибка компиляции

    • <script>{</script>
    • <script>for(;)</script>
    • <script>"oops</script>
    • setTimeout("{", 10);, он попытается скомпилировать первый аргумент как script

Но две основные проблемы, описанные здесь красиво:

  • В отличие от локального блока try/catch, обработчик window.onerror doesnt имеют прямой доступ к объекту исключения и выполняются в глобальный контекст, а не локально, где произошла ошибка. Что означает, что разработчики не имеют доступа к стеку вызовов и не могут сами создайте стек вызовов, пройдя цепочку методов звонящие.

  • Браузеры подходят для дезинфекции данных, предоставляемых обработчика, чтобы предотвратить непреднамеренную утечку данных из скрипты с кросс-началом. Если вы размещаете свой JavaScript на CDN (как вы ), вы получите "Script error.", "" и 0 в вышеперечисленном обработчике. Это не особенно полезно.

Ответ 2

Не совсем прямой ответ на ваш вопрос, но если вы хотите уменьшить вероятность ненаблюдаемых ошибок JavaScript, опечаток и вообще улучшить свой стиль кодирования JavaScript, рассмотрите возможность использования Строгого режима JavaScript ("use strict";). Он поддерживается всеми современными браузерами и обратно совместим со старыми. Некоторые соответствующие ресурсы для начала:

HTML-документ должен быть в стандартном режиме, чтобы иметь возможность использовать строгий режим JavaScript. Пример:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title></title>
    <script type="text/javascript">
        window.func1 = function() {
            "use strict";
            return (eval("var __temp = null"), (typeof __temp === "undefined")) ? 
                "strict": 
                "non-strict";
        }

        window.func2 = function() {
            return (eval("var __temp = null"), (typeof __temp === "undefined")) ? 
                "strict": 
                "non-strict";
        }

        window.onload = function() {
            info.firstChild.data = 
                "\ndocument.compatMode: " + document.compatMode +
                "\nfunc1: " + func1() +
                "\nfunc2: " + func2();
        }
    </script>
</head>
<body>
    <pre id="info">&nbsp;</pre>
</body>
</html>

Выход:

document.compatMode: CSS1Compat
func1: strict
func2: non-strict