Отчеты об исключениях JS для интерфейсных полных (отсутствующих) скрытых точек
Цзо Пэнфэй 2017.11.29
Связанное Чтение
1. Введение
Отчет об ошибках JS — относительно распространенный сценарий, но есть некоторые ошибки: например, поля внутреннего интерфейса изменились, что привело к ошибке времени выполнения на внешнем интерфейсе; тогда мы не можем проверить это, когда тестируем локально, только после публикация в Интернете. Возможны исключения. Если спасение будет своевременным, это хорошо, но если оно будет обнаружено поздно, это может привести к большим потерям. Если наш внешний интерфейс сможет отслеживать такого рода ошибки и вовремя сообщать о них, тогда наша проблема будет решена лучше.
2. Что такое исключение внешнего кода JS
Исключения внешнего кода относятся к следующим двум ситуациям:
-
В сценарии JS есть синтаксические ошибки;
-
Произошла ошибка во время выполнения JS-скрипта.
3. Что должна включать информация об исключении ошибки
-
message {String} Сообщение об ошибке. Интуитивно понятное описание ошибки.
-
url {String} Путь к сценарию, соответствующий ошибке, такой как вашa.jsВсе еще неправильноb.jsсообщил об ошибке.
-
lineNo {Number} Номер строки, в которой произошла ошибка.
-
columnNo {Число} Номер столбца, в котором произошла ошибка.
-
error {Object} Конкретный объект ошибки, который содержит более подробную информацию о стеке вызовов ошибок, что очень полезно для обнаружения ошибок.
4. попытка поймать исключение
- try-catch может захватить код ошибки, который выполняется при внутреннем
- Если есть обещание, асинхронный код не может нормально перехватывать исключения.
- Если вы хотите захватить глобальные события ошибок, вам нужно упаковать try-catch для всего кода: обычная практика заключается в том, чтобы упаковать весь упакованный JS снаружи с помощью try-catch; каждый метод должен быть упакован в try-catch внутри.
- Обычно необходимо реализовать пакет try-cath с помощью инженерных средств: например:babel-plugin-try-catch-wrapper
5. Событие window.onerror перехватывает исключение
5.1 Проблемы совместимости
- Сообщение с описанием ошибки из этого не видно, особенно сообщение об ошибке сжатого скрипта.
- Разные браузеры имеют разные сообщения для одной и той же ошибки.
- Браузер IE10 может получить только сообщение, URL-адрес и номер строки, номер столбца и конкретную ошибку нельзя получить, однако объект window.event предоставляет errorLine и errorCharacter для соответствия соответствующей информации о номере строки и столбца.
//不一定所有浏览器都支持col参数,如果不支持就用window.event来兼容
col = col || (window.event && window.event.errorCharacter) || 0;
скопировать код
- Вы можете использовать arguments.callee.caller для рекурсии из стека вызовов, этот тип информации является наиболее прямым сообщением об ошибке.
if (error && error.stack){
//如果浏览器有堆栈信息,直接使用
defaults.msg = error.stack.toString();
}else if (arguments.callee){
//尝试通过callee拿堆栈信息
var ext = [];
var fn = arguments.callee.caller;
var floor = 3; //这里只拿三层堆栈信息
while (fn && (--floor>0)) {
ext.push(fn.toString());
if (fn === fn.caller) {
break;//如果有环
}
fn = fn.caller;
}
ext = ext.join(",");
defaults.msg = error.stack.toString();
}
скопировать код
5.2 Другие примечания
-
Скрипт window.onerror должен быть размещен вверху всего кода, иначе часть информации об исключении не будет захвачена, т.к. возникает исключение, js не будет выполняться вниз
-
Для ресурсов с перекрестным доменом js (обычно код захвата исключений включен под основным доменным именем, и другие статические ресурсы находятся на статическом кластере CDN), по умолчанию, когда сообщение об ошибке скрипта с перекрестным доменом в этом доменном имени , только ошибка скрипта сообщения. Получается. Получается. Получается информация о файлах, отсутствие данных, нет данных строки и столбца и нет подробного объекта ошибок. Для Window.oneRror подробная информация не может быть получена, а дополнительные заголовки должны быть добавлены в запрос ресурса. Запрос на статический ресурс должен добавить заголовок для управления доступом, то есть заголовок доступа-элемента управления доступом должен быть добавлен в фоновом режиме, а атрибут кроссоригина должен быть добавлен в тег, который Сценарий вводит в внешнюю цепочку. Таким образом, можно получить точную информацию об ошибке.
-
В настоящее время статические файлы сценариев большинства сайтов должны быть сжаты и запутаны, когда они выходят онлайн. Таким образом, когда происходит ошибка, полученный номер строки является строкой 1, а номер столбца будет огромным числом. На этом этапе вы можете полагаться только на сообщение об ошибке и пути файла, чтобы найти ошибку. К счастью, у нас есть SourceMap, с ним мы можем найти местоположение исходного кода. О SourceMap, эта статья РуанскойДетальное объяснениеВы можете узнать о исходной карте Принцип Mozilla с открытым исходным кодомsourcemapВы можете положиться на него для создания исходной карты или обратного вычисления имен переменных и номеров строк и столбцов на основе исходной карты.
-
Когда возникает ошибка, объем сообщаемых данных все еще довольно велик. Если исключение запускается неоднократно и непрерывно бомбардирует сервер, это не только избыточные данные, но и пустая трата трафика. Таким образом, сообщения об аномальной информации должны быть ограничены с точки зрения содержания сообщений и частоты сообщений.
//采用异步的方式,避免阻塞
setTimeout(function() {
//不一定所有浏览器都支持col参数,如果不支持就用window.event来兼容
col = col || (window.event && window.event.errorCharacter) || 0;
defaults.url = url;
defaults.line = line;
defaults.col = col;
if (error && error.stack){
//如果浏览器有堆栈信息,直接使用
defaults.msg = error.stack.toString();
}else if (arguments.callee){
//尝试通过callee拿堆栈信息
var ext = [];
var fn = arguments.callee.caller;
var floor = 3; //这里只拿三层堆栈信息
while (fn && (--floor>0)) {
ext.push(fn.toString());
if (fn === fn.caller) {
break;//如果有环
}
fn = fn.caller;
}
ext = ext.join(",");
defaults.msg = error.stack.toString();
}
}, 0);
скопировать код
6. Резюме
QA не всемогущ. Пользовательская среда просмотра очень сложна, и многие ситуации не могут быть охвачены тестовыми примерами. Поэтому лучше всего создать внешний журнал ошибок для сбора ошибок на стороне реального пользователя.