likes
comments
collection
share

常见的前端异常处理

作者站长头像
站长
· 阅读数 10

前端异常/错误处理

错误处理对于任何前端来说都是必不可少的。任何人写代码都避免不了会有bug,而且很多bug也不是测试用例能完全覆盖的,如果我们没有一个完整的错误处理和错误收集的系统,我们都无法知道我们有bug,不仅如此,很多bug也不一定是前端的问题,比如某个接口返回的数据格式不对了或者少字段了,亦或是在某个特定的浏览器上才有的问题等等。有了错误处理和收集,我们才能更好的通过错误栈来还原这个问题。

有哪些错误需要处理

  • JS 语法错误、代码异常
  • 请求错误
  • 静态资源加载异常
  • Promise异常
  • Iframe异常
  • 跨域Script error
  • 页面崩溃和卡顿

Try Catch

try-catch 只能捕获到同步运行时错误,对语法和异步错误却无能为力,捕获不到。

1.同步运行时错误

try {
  let name = 'foo';
  console.log(nam);
} catch (e) {
  console.log('捕获到异常:', e);
}

捕获到异常: 'ReferenceError: nam is not defined at <anonymous>:3:15'

2.语法错误

try {
  let name = 'foo
  console.log(nam);
} catch (e) {
  console.log('捕获到异常:', e);
}

Uncaught SyntaxError: Unexpected identifier

3.异步错误

try {
  setTimeout(() => {
    undefined.map(v => v);
  }, 1000)
} catch (e) {
  console.log('捕获到异常:', e);
}

Uncaught TypeError: Cannot read property 'map' of undefined

可以看出,try/catch并没有捕获到异步错误

window.onerror

当 JS 运行时错误发生时,window 会触发一个 ErrorEvent 接口的 error 事件,并执行 window.onerror()。

/**
 * @param {String}  message 错误信息
 * @param {String}  source 出错文件
 * @param {Number}  lineno 行号
 * @param {Number}  colno 列号
 * @param {Object}  error Error错误对象(对象)
 */
window.onerror = function(message, source, lineno, colno, error) {
  console.log('捕获到异常:', { message, source, lineno, colno, error });
}

不同域名下的 js 报错不能被 全局的 window.onerror 监听到,我们需要给相关的 js 文件上加上 Access-Control-Allow-Origin:*的 response header,并且引用相关的 js 文件时加上 crossorigin 属性。相关文章

在实际的使用过程中,onerror 主要是来捕获预料之外的错误,而 try-catch 则是用来在可预见情况下监控特定的错误,两者结合使用更加高效。

window.addEventListener

当一项资源(如图片或脚本)加载失败,加载资源的元素会触发一个Event接口的error事件,并执行该元素上的onerror()处理函数。这些error事件不会向上冒泡到 window ,不过(至少在 Firefox 中)能被单一的 window.addEventListener 捕获。

<img src="./foo.png">
<scritp>
window.addEventListener('error', (error) => {
  console.log('捕获到异常:', error);
}, true)
</script>

Promise Catch

没有写 catch 的 Promise 中抛出的错误无法被 onerror 或 try-catch 捕获到,所以我们务必要在 Promise 中不要忘记写 catch 处理抛出的异常。

或者可以全局增加一个对 unhandledrejection 的监听,用来全局监听 Uncaught Promise Error。使用方式:

window.addEventListener('unhandledrejection', function(e) {
  console.log(e);
})

async/await异常捕获:

实际上async/await语法本质还是Promise语法。

区别就是async方法可以被上层的try/catch捕获。

当然你如果使用如 axios 这种库的话,错误处理完全可以放在它的请求实例里面做。更加的灵活。

VUE errorHandler

Vue.config.errorHandler = (err, vm, info) => {
  console.error('通过vue errorHandler捕获的错误');
  console.error(err);
  console.error(vm);
  console.error(info);
}

React 异常捕获

componentDidCatch(error, info) {
  console.log(error, info);
}

从0到1搭建异常监控系统

从零搭建系统化前端异常监控系统:相关文章