常见的前端异常处理(前端开发遇到的问题及解决方法)
前端异常/错误处理
错误处理对于任何前端来说都是必不可少的。任何人写代码都避免不了会有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); }
作者:w小p
链接:https://juejin.cn/post/7048450212431396878