全局监控Promise错误

一、问题引入

Promise 在前端中的使用已经非常普遍了,但是许多开发者或许习惯了链式调用却忘了捕获 Promise 的错误了。

例如:

function forgetCatchError () {
  async()
    .then(() => {
      // code..
    })
    .then(() => console.log('forget catch error!'));
}

上面的示例代码中 async() 中和后续的两个 then 中的代码如果出错或者 reject ,错误没有得到处理。

在没有使用 catch 方法指定错误处理的回调函数,Promise 对象抛出的错误不会传递到外层代码,即不会有任何反应。当promise被 reject 并且错误信息没有被处理的时候,会抛出 unhandledrejection,这个错误不会被 window.onerroraddEventListener("error") 所监听到。

二、try catch

// 示例
async function fn() {
  let value = await new Promise((resolve, reject) => {
    reject('failure');
  });
  console.log('do something...');
}
fn()

未使用try catch,导致浏览器报错:一个未捕获的错误

所以在开发过程中,为了保证系统健壮性,或者是为了捕获异步的错误,需要频繁的在 async 函数中添加 try/catch,避免出现示例的情况

注:可以引入插件如babel编译插件(babel-plugin-await-add-trycatch),给全局async await添加 try catch代码块

三、全局监控方法

对 unhandledrejection 事件进行监听即可捕捉到未被 catch 的 Promise 错误。

window.addEventListener("unhandledrejection", err => {
  console.log(err.reason)

  err.preventDefault();
}, false);

 // 或者
 window.onunhandledrejection = function(err) {
  console.log(err.reason);
  return true;
}

addEventListener 中调用 event 的 preventDefault() 可以让 Promise 的错误不抛送到控制台,在 onunhandledrejection 中则可以使用 return true 来达到相同的效果。

 

posted @ 2022-11-22 09:51  盼星星盼太阳  阅读(594)  评论(0编辑  收藏  举报