试试Atatus,它为现代网络应用提供高级错误跟踪和真实用户监控。
https://www.atatus.com/
让我解释一下如何在所有浏览器中获得相当完整的堆栈跟踪。
JavaScript 中的错误处理
现代 Chrome 和 Opera 完全支持 ErrorEvent 和 window.onerror 的 HTML 5 草案规范。在这两种浏览器中,您都可以使用window.onerror,或正确绑定到“错误”事件:
// 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
// sendError(data);
};
// Only Chrome & Opera have an error attribute on the event.
window.addEventListener("error", function (e) {
console.log(e.error.message, "from", e.error.stack);
// You can send data to your server
// sendError(data);
})
不幸的是,Firefox、Safari 和 IE 仍然存在,我们也必须支持它们。由于堆栈跟踪在 window.onerror 中不可用,我们必须做更多的工作。
事实证明,要从错误中获取堆栈跟踪,我们唯一能做的就是将所有代码包装在 try{ }catch(e){ } 块中,然后查看 e.stack。我们可以使用一个名为 wrap 的函数来简化这个过程,该函数接受一个函数并返回一个具有良好错误处理能力的新函数。
function wrap(func) {
// Ensure we only wrap the function once.
if (!func._wrapped) {
func._wrapped = function () {
try{
func.apply(this, arguments);
} catch(e) {
console.log(e.message, "from", e.stack);
// You can send data to your server
// sendError(data);
throw e;
}
}
}
return func._wrapped;
};
这行得通。您手动包装的任何函数都会有很好的错误处理,但事实证明,在大多数情况下,我们实际上可以自动为您完成。
通过更改addEventListener 的全局定义,使其自动包装回调,我们可以在大多数代码周围自动插入try{ }catch(e){ }。这让现有代码继续工作,但增加了高质量的异常跟踪。
var addEventListener = window.EventTarget.prototype.addEventListener;
window.EventTarget.prototype.addEventListener = function (event, callback, bubble) {
addEventListener.call(this, event, wrap(callback), bubble);
}
我们还需要确保removeEventListener 继续工作。目前不会,因为addEventListener 的参数已更改。同样,我们只需要在 prototype 对象上解决这个问题:
var removeEventListener = window.EventTarget.prototype.removeEventListener;
window.EventTarget.prototype.removeEventListener = function (event, callback, bubble) {
removeEventListener.call(this, event, callback._wrapped || callback, bubble);
}
将错误数据传输到您的后端
您可以使用图像标签发送错误数据,如下所示
function sendError(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;
}
免责声明:我是https://www.atatus.com/ 的网络开发人员。