При написании кода на любом языке программирования никогда не получается обходиться без ошибок, даже если программа протестирована уже в сотый раз. И язык JavaScript тоже не исключение. Ошибки не перехваченные в коде программы, могут остановить выполнение остальных скриптов на странице. Но так как ошибка находится н...
При написании кода на любом языке программирования никогда не получается обходиться без ошибок, даже если программа протестирована уже в сотый раз. И язык JavaScript тоже не исключение. Ошибки не перехваченные в коде программы, могут остановить выполнение остальных скриптов на странице. Но так как ошибка находится на стороне браузера пользователя, ее не получится увидеть, если не использовать специальных механизмов отслеживания клиентских ошибок и сохранения их на сервере.
Далее, рассмотрим пример установки глобального обработчика ошибок на странице, который будет отсылать информацию об ошибке на сервер.
Итак, код обработчика:
let hasLoggedOnce = false;
// Некоторые браузеры не сообщают номера строк и столбцов
// когда событие обрабатывается с помощью window.addEventListener('error', fn). Вот почему
// более надежным подходом является установка прослушивателя событий с помощью прямого назначения обработчика.
window.onerror = function (eventOrMessage, url, lineNumber, colNumber, error) {
if (hasLoggedOnce || !eventOrMessage) {
// Не имеет смысла сообщать об ошибке, если:
// 1. уже сообщалось о другой ошибке - страница находится в недопустимом состоянии и может выдавать слишком много ошибок.
// 2. предоставленная информация не имеет смысла (нет события или сообщения - браузер по какой-то причине не предоставил информацию).
return;
}
hasLoggedOnce = true;
if (typeof eventOrMessage !== 'string') {
error = eventOrMessage.error;
url = eventOrMessage.filename || eventOrMessage.fileName;
lineNumber = eventOrMessage.lineno || eventOrMessage.lineNumber;
colNumber = eventOrMessage.colno || eventOrMessage.columnNumber;
eventOrMessage = eventOrMessage.message || eventOrMessage.name || error.message || error.name;
}
if (error && error.stack) {
eventOrMessage = [eventOrMessage, '; Stack: ', error.stack, '.'].join('');
}
const jsFile = (/[^/]+\.js/i.exec(url || '') || [])[0] || 'inlineScriptOrDynamicEvalCode';
let stack = [eventOrMessage, 'Ошибка появилась ', jsFile, ':', lineNumber || '?', ':', colNumber || '?'].join('');
// немного сокращаем сообщение, чтобы оно с большей вероятностью соответствовало ограничению длины URL-адреса браузера (которое в некоторых браузерах составляет 2083 символа).
stack = stack.replace(/https?\:\/\/[^/]+/gi, '');
// вызов обработчика на стороне сервера, который, должен зарегистрировать ошибку в базе данных или файле журнала
// заставляем браузер отправить информацию на сервер посредством загрузки изображения размером 1x1
new Image().src = '/clientError?stack=' + encodeURIComponent(stack);
// window.ENVIRONMENT_DEV - настраиваемое свойство, которому может быть присвоено значение true где-либо еще для целей отладки и тестирования
if (window.ENVIRONMENT_DEV) {
alert('Клиентская ошибка: ' + stack);
}
}
Таким образом, мы создали обработчик клиентских ошибок и логирования их на сервер.
