常见的前端异常处理
前端异常/错误处理
错误处理对于任何前端来说都是必不可少的。任何人写代码都避免不了会有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搭建异常监控系统
从零搭建系统化前端异常监控系统:相关文章
转载自:https://juejin.cn/post/7048450212431396878