问题的前提是:
搭建一个自动捕获web页面错误的脚本,捕获到错误的时候把错误上报到服务器。
我的代码类似于:
window.onerror = (message, url, lineNo, columnNo, errorObj) => {
//使用 Object.getOwnPropertyNames 是因为想要获取 error的所有可访问属性。
var originErrorCloned = Object.getOwnPropertyNames((errorObj || {})).reduce(function(result, key){
result[key] = error[key];
return result;
}, {});
// 发送错误到服务器
fetch('xxx', {body: JSON.stringify({error: originErrorCloned})})
};
在服务端查看上报的数据的时候,发现存在空对象的错误
{"error": "{}"}
其他的正常上报的数据应该是类似于这样的:
{
"error": "{\"stack\":\"xxx\\n xxx \\n xxx \\n",\"message\":\"Cannot read property 'xxxx' of undefined\"}"
}
之前也采用过 另一种直接访问error对象属性的上报方式,但是获得的结果是一样的
window.onerror = (message, url, lineNo, columnNo, errorObj) => {
fetch('xxx', {body: JSON.stringify({
message: errorObj.message,
stack: errorObj.stack,
name: errorObj.name
})});
};
所以我猜测 errorObj 被捕获的时候就是一个 没有message、stack、name 的 对象;
原因是 JSON.stringify 在 字符串化对象的时候,会把值为undefined的key忽略,导致上报到服务器拿到的是"{error: "{}"}",所以我后来改用上面的 Object.getOwnPropertyNames 方式遍历所有可访问的key来重新生成一个普通的Object来上报;
我搞不清楚的问题是:
1.为什么window.onerror 拿到的 错误对象 会是一个 空的错误对象,要怎么才能上报这种特殊的错误对象?
2.如果拿到的errorObj是个null 或者undefined,那么按照我旧的上报方式的话,访问 errorObj.message 的时候就会报错了,不会继续发送到服务器(真正的代码结构不一样,先构造对象后http请求)
环境:根据几天来的数据分析,发现大部分是来自 applewebkit(safari、chrome) 和 gecko(firfox) 的windowsPC上报