本次写作来源于一次面试,前端架构师岗位,最后面试官临时给我掏出了一道比较少见的面试题 ,终究斩获offer ,虽然这道题并不难,但是考察的东西挺有趣,加上近期有看到前端防御性编程、优雅处理前端错误的文章,于是想起来把这道题写了下来。
本题答案: xxxx未定义,致命错误,之前无错误捕获处理机制,页面没有跳转到百度
这里还是比较简单,因为try里面才会捕获错误,一旦抛出错误就会被全局捕获错误的函数捕获 最终输出顺序: try 抛出错误 全局捕获到错误
这里主要考察的是函数的抛出错误配合finally的执行,我们一直认为,只要函数内部抛出错误,就会结束这个函数调用,立马出栈。所以return和throw new Error不能在一起用,但是finally却还是依然会执行。 finally,顾名思义,最后都会执行
如果此时其他模块发生了致命错误,例如const这种代码跑在IE6中,那么就会直接致命错误,阻断浏览器解析代码,页面挂掉。js引擎也不会去解析下面的代码~ 还没有运行到window.onerror这里就挂了
上面只是一个比较简单的面试题,考察错误处理能力,后面是结合React的错误边界,资源请求错误,ajax请求错误等的处理来口述,这里可能需要你平时对这些东西有比较多了解和实践才能hold住
使用window.onerror和window.addEventListener('error')都能捕获,但是window.onerror含有详细的error堆栈信息,存在error.stack中,所以我们选择使用onerror的方式对js运行时错误进行捕获。
实现原理:当一项资源(如<img>或<script>)加载失败,加载资源的元素会触发一个Event接口的error事件,并执行该元素上的onerror()处理函数。
这些error事件不会向上冒泡到window,不过能被window.addEventListener在捕获阶段捕获。
伪代码
window.addEventListener('error', (e) => {
这样就可以捕获到任意的图片等资源加载错误的信息,但是捕获后依旧会有爆红提示,我猜想这种资源请求错误是非常重要的,必须爆出来?
有人说使用 create-react-app 创建的项目,在开发环境,就算使用了 componentDidCatch 或者 getDerivedStateFromError,错误依然会被抛出,在 build 后,错误将会捕获,不会导致整个项目卸载(这点我不确定,因为我都是自己配脚手架的)
根据官方文档所说,在 react 16 以后,任何未被错误边界捕获的错误将会导致整个 React 组件树被卸载。所以我们在开发项目时,需要去捕获错误边界的错误,并提供一个备用UI,那么被错误边界捕获的错误,还会冒泡到window中吗
我们先定义一个错误边界,然后html模板文件中,依旧有我们的那段代码
此时React根组件的componentDidmount生命周期函数抛出错误
抛出错误后,被错误边界捕获
说明这种错误被React错误边界捕获后,就不会再被onerror函数捕获,那么window.addEventListenr呢? 尝试一下。
最终被全局到error回调函数捕获,但是大家很奇怪,这里为什么捕获了,还会爆出错误?我们之前是不会的。
这里要说明一点,如果是人为抛出错误 throw new Error,error函数是可以捕获的。但是一旦是语法错误,那么需要在error函数中return true,这样异常才不会往上继续抛出。
细心的朋友会发现,控制台一直有一个报错,没错,这是一个静态资源的请求,img标签。
<img src="ssss" alt=""/>
**这里可以确定,静态资源请求错误,不会冒泡到window.error事件中,只可以通过上面的dom2形式通过在捕获阶段捕获到这个错误
**
window.addEventListener('error', (e) => {
<img src="ssss" alt="" onError={(e)=>{console.log('图片加载失败',e)}}/>
Promise的捕获, 对于频繁调用的函数,肯定是需要封装成promise风格的,统一处理错误,统一接口捕获一次就可以了 , 因为onerror函数并不能捕获promise错误,这里我就不演示了
> 网络请求错误也是不会被error函数捕获的,但是我们可以封装成promise风格,统一自己catch错误处理
new Image().src = `${url}?err=${error}`;
由于现在的错误监控、上报已经形成了一套完整的商业链,这方面并不是我的强项,如果写得不对的地方,欢迎指出 ,架构师岗位面试,更考察你对项目整体把控能力,最后出现这个题目,我觉得也正常
https://github.com/JinJieTan/react-webpack
如果感觉写得不错,可以帮忙点个-在看
希望每个人都会像老许一样
有人问你,你要老婆/老公不要?
要的话,就给你送来
关注公众号,回复:加群 即可进入交流群~