错误监控&错误捕获
可能会发生的错误有很多类型,每种错误都有对应的错误类型,而当错误发生的时候,就会抛出响应的错误对象。ECMA-262 中定义了下列 7 种错误类型:
在 js 执行期间
- Error 错误的基类,其他错误都继承自该类型 
- RangError 数组越界 
- EvalError: Eval 函数执行异常 
- ReferenceError 尝试引用一个未被定义的变量时,将会抛出此异常 
- SyntaxError 语法解析不合理 
- TypeError 类型错误,用来表示值的类型非预期类型时发生的错误 
- URLError 以一种错误的方式使用全局 URL 处理函数而产生的错误 
异常处理
JavaScript 引擎首先会读取代码,然后运行它。在读取阶段发生的错误被称为“解析时间(parse-time)”错误,并且无法恢复(从该代码内部)。这是因为引擎无法理解该代码。
所以,try..catch 只能处理同步代码中出现的错误。这类错误被称为“运行时的错误(runtime errors)”,有时被称为“异常(exceptions)”。
try {
  setTimeout(function () {
    noSuchVariable; // 脚本将在这里停止运行
  }, 1000);
} catch (e) {
  alert("won't work");
}当 JS 运行时错误发生时,window 会触发一个 ErrorEvent 接口的 error 事件,并执行 window.onerror()。
window.onerror = function (msg, url, row, col, error) {
  console.log("🌸", msg); //能捕获到异步错误
  return true;
};同步错误可以捕获到,但是,请注意 window.onerror 无法捕获静态资源异常和 JS 代码错误。
try catch 不能捕获到 promise.resolve()的报错
try...catch 只能捕获同步代码中的异常。对于异步操作,错误是在异步任务执行时抛出的,而 try...catch 已经执行完毕,无法捕获这些错误。
try {
  new Promise((resolve, reject) => {
    throw new Error("Error inside Promise");
  });
} catch (e) {
  console.error("Caught:", e);
}静态资源加载异常
方法一: onerror 来捕获
<script>
  function errorHandler(error) {
    console.log("捕获到静态资源加载异常", error);
  }
</script>
<script src="http://cdn.xxx.com/js/test.js" onerror="errorHandler(this)"></script>
<link rel="stylesheet" href="http://cdn.xxx.com/styles/test.css" onerror="errorHandler(this)">方法二: addEventListener('error')
window.addEventListener(
  "error",
  () => {
    console.log("🌸", msg); //能捕获到异步错误
  },
  true
);由于网络请求异常不会事件冒泡,因此必须在捕获阶段将其捕获到才行
Promise 异常
// 捕获全局 promise 错误
window.addEventListener("unhandledrejection", function (e) {
  e.preventDefault();
  console.log(e.reason);
  // 消化错误, 则需要显示返回true
  return true;
});
new Promise((resolve, reject) => {
  reject("第一个 error");
});
Promise.reject("第二个错误");错误的传递
- 用户 xpath 用户操作栈 
- 服务端 xpath mp4=> gif 
- socket 图片 html2canvas 
- session statck 
- 容错 数据的时候 ajax navigator.sendBeacon('xx.php') 
在 Node 中,
- unhandeleRejection 在一个事件循环中,当 Promise 被拒绝,并且没有提供任何处理程序的时候,触发该事件 
- rejectionHandled 在一个事件循环后,当 Promise 被拒绝时,若拒绝处理程序被调用,触发该事件 
捕获到错误后,我们需要思考当错误发生时:
- 如果是服务器未知异常导致,可以阻塞用户操作,弹窗提示用户『服务器异常,请稍后重试』,并提供给用户一个刷新的按钮 
- 如果是数据异常导致,可阻塞用户操作,弹窗提示用户『服务器异常』,同时将错误信息上报异常服务器,开发人员通过异常堆栈和用户埋点定位问题原因 
错误的收集方式
- 可疑区域增加 try-catch 
- 全局监控 JS 异常 window.onerror 
- 全局监控静态资源异常 window.addEventListener 
- 捕获没有 catch 的 Promise 异常用 unhandledrejection 
- Vue errorHandler 和 React componentDidCatch 
- Axios 请求统一异常处理用拦截器 interceptors 
- 使用日志监控服务收集用户错误信息 
最后更新于
这有帮助吗?