Как мы отслеживаем ошибки Javascript? Действуют ли существующие инструменты?
Сегодня я нахожу необходимость отследить и получить трассировку стека ошибок Javascript для их решения.
Сегодня мы смогли перехватить все остальные вызовы, идея состоит в том, что, как только вы получите ошибку, она автоматически публикует трассировку стека этой ошибки плюс ответы остальных сохраненных сервисов, чтобы мы могли обнаруживать, воспроизводить и решать проблемы практически идентично окружающая среда/положение.
В качестве требования нас попросили сделать модуль, который можно было бы включить без навязчивости, например:
Включение модуля, который содержит логику хука в одном JS, будет неинвазивным, включение нескольких строк кода в различные JS файлы будет инвазивным.
Цель состоит в том, чтобы создать инструмент, который можно включить в уже разработанную систему, и отслеживать события ошибок (например, консоль).
Я читал об этой логике трекера:
- errorception.com/
- trackjs.com/
- atatus.com/
- airbrake.io/
- jslogger.com/
- getsentry.com/
- muscula.com/
- debuggify.net/
- raygun.io/home
Нам нужно сделать что-то подобное, отследить ошибку и отправить ее на наш сервер.
Как говорит "Dagg Nabbit"..."Трудно получить трассировку стека по ошибкам, которые происходят прямо сейчас"
Итак, у нас есть много платных продуктов, но как они действительно работают?
В Airbrake они используют stacktrace и window.onerror:
window.onerror = function(message, file, line) {
setTimeout(function() {
Hoptoad.notify({
message : message,
stack : '()@' + file + ':' + line
});
}, 100);
return true;
};
Но я не могу понять, когда реально использовалась трассировка стека.
В какой-то момент stacktrace, raven.js и другие трекеры нуждаются в try/catch.
- что произойдет, если мы найдем способ создать глобальную оболочку?
- Можем ли мы просто вызвать трассировку стека и дождаться улова?
Как я могу отправить трассировку стека на мой сервер, когда на клиенте возникает непредвиденная ошибка? Любой совет или хорошие практики?
Ответы
Ответ 1
Трудно получить трассировку стека от ошибок, которые происходят "в дикой природе" прямо сейчас, потому что объект Error недоступен для window.onerror
.
window.onerror = function(message, file, line) { }
Существует также новое событие error
, но это событие не предоставляет объект Error (пока).
window.addEventListener('error', function(errorEvent) { })
Вскоре window.onerror
получит пятый параметр, содержащий объект Error, и вы, вероятно, можете использовать stacktrace.js, чтобы захватить трассировку стека во время window.onerror
.
<script src="stacktrace.js"></script>
<script>
window.onerror = function(message, file, line, column, error) {
try {
var trace = printStackTrace({e: error}).join('\n');
var url = 'http://yourserver.com/?jserror=' + encodeURIComponent(trace);
var p = new printStackTrace.implementation();
var xhr = p.createXMLHTTPObject();
xhr.open('GET', url, true);
xhr.send(null);
} catch (e) { }
}
</script>
В какой-то момент API ошибок, вероятно, будет стандартизован, но на данный момент каждая реализация отличается, поэтому, вероятно, разумно использовать что-то вроде stacktracejs для захвата трассировки стека, поскольку для этого требуется отдельный путь кода для каждого браузера.
Ответ 2
Я являюсь соучредителем TrackJS, упомянутым выше. Вы правы, иногда получение трассировки стека требует немного работы. На некотором уровне функции асинхронизации должны быть завернуты в блок try/catch, но мы делаем это автоматически!
В TrackJS 2.0+ любая функция, которую вы передаете в обратный вызов (addEventListener
, setTimeout
и т.д.), будет автоматически завершена в try/catch. Мы обнаружили, что с этим можно поймать почти все.
Для тех немногих вещей, которые мы можем сейчас, вы всегда можете попробовать/поймать их самостоятельно. Мы предоставляем некоторые полезные обертки, чтобы помочь, например:
function foo() {
// does stuff that might blow up
}
trackJs.watch(foo);
Ответ 3
В последних браузерах существует 5-й параметр для объекта ошибки в window.onerror
.
В addEventListener
вы можете получить объект ошибки event.error
// Only Chrome & Opera pass the error object.
window.onerror = function (message, file, line, col, error) {
console.log(message, "from", error.stack);
// You can send data to your server
// sendData(data);
};
// Only Chrome & Opera have an error attribute on the event.
window.addEventListener("error", function (event) {
console.log(e.error.message, "from", event.error.stack);
// You can send data to your server
// sendData(data);
})
Вы можете отправлять данные с помощью тега изображения следующим образом
function sendData(data) {
var img = newImage(),
src = http://yourserver.com/jserror + '&data=' + encodeURIComponent(JSON.stringify(data));
img.crossOrigin = 'anonymous';
img.onload = function success() {
console.log('success', data);
};
img.onerror = img.onabort = function failure() {
console.error('failure', data);
};
img.src = src;
}
Если вы ищете openource, вы можете проверить TraceKit. TraceKit выдавливает как можно больше полезной информации и нормализует ее. Вы можете зарегистрировать подписчика для отчетов об ошибках:
TraceKit.report.subscribe(function yourLogger(errorReport) {
// sendData(data);
});
Однако вам нужно сделать бэкэнд для сбора данных и интерфейсов для визуализации данных.
Отказ от ответственности: Я - веб-разработчик на https://www.atatus.com/, где вы можете отслеживать все ваши ошибки и фильтр JavaScript ошибки в разных размерах, такие как браузеры, пользователи, URL-адреса, теги и т.д.
Ответ 4
@Da3 Вы спросили о appenlight и stacktraces. Да, он может собирать полные стеки стека, пока вы завершаете исключение в блоке try/catch. В противном случае он попытается прочитать информацию из window.onerror, которая очень ограничена. Это ограничение браузера (которое может быть исправлено в будущем).