为什么我在web项目里全局捕获的错误里会有空的错误对象?

问题的前提是:
搭建一个自动捕获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上报

阅读 1.2k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题