前序
记一次上线前才暴露出的bug引发的思考,原本周三晚上可以正常下班回家吃饭的,却因一个bug整的9点才回去,内心平静,没有丝毫波澜。
问题
事情是这样的,测试同事在快下班前提出了一个bug,预生产环境上的页面头部导航栏不见了,本以为是个小问题,很快能解决,以为最多就是个v-if条件判断而已,可当我们打开代码时发现事情并没有那么简单,因为头部组件上压根没有条件判断,而且我们本地run也是正常的,只有在预生产环境才会出现这个问题,本地复现不了,这可难受了啊,怎么办呢? 硬着头皮干,慢慢看代码呗,想想有哪些可能?最近几点谁改了这个文件?
原因
果然,最后定位到是另一位同事写的代码导致了这个问题的发生,把他写的代码注释掉之后,预生产就正常了,但是他的功能还是要上啊,他人还不在,只能帮他改,内心早已带上了痛苦面具,接下来就模拟可能的原因,最终定位到了。
最终原因:他没有做代码健壮性处理,正常来说在vue组件中你在模板中使用了一个不存在的对象属性的时候,他是会编译不通过,会直接报错,如图所示
可是巧了,本地run的时候一切请求都是正常的,所以本地一开始无法复现线上问题,他的原代码是这样的
// 登录组件中在sessionStorage中存储questionLink值
this.$http.get('*****', { params }).then((data) => {
this.questionLink = data.data.result.list[0];
sessionStorage.setItem('questionLink', JSON.stringify(this.questionLink));
});
// 头部组件中引用sessionStorage中存储questionLink值
questionLink() {
return JSON.parse(sessionStorage.getItem('questionLink'));
},
没有做任何的健壮性处理,请求报错就直接GG
JSON.stringify()这一步处理的时候,this.questionLink有可能是undefined,导致存进sessionStorage去的是字符串‘undefined’,再经过JSON.parse()解析就直接报错,导致头部组件模板没有渲染出来的一系列问题,坑啊
解决
最后修改过后,代码如下
this.$http.get('*****', { params }).then((data) => {
this.questionLink = data?.data?.result?.list?.[0] || {}; // 健壮性处理
sessionStorage.setItem('questionLink', JSON.stringify(this.questionLink));
});
questionLink() {
// 健壮性处理
if (
sessionStorage.getItem('questionLink') === 'undefined'
|| sessionStorage.getItem('questionLink') === 'null'
|| !sessionStorage.getItem('questionLink')
) {
return {};
}
return JSON.parse(sessionStorage.getItem('questionLink'));
},
总结
大家在写代码时一定要严谨一点,一定要做代码健壮性处理,不然就会有可能出现这样的情况,js没有静态类型检查,导致了如果不做健壮性处理就可能在线上冒出各种花里胡哨的问题,不过这一点也确实体现出了typescript的优势,静态类型检查,在编译时就会把问题抛出来,能够让你的代码更稳定(安全)一点