2017年快要过去了,回顾这一年来,在业务代码里,开发新功能占据70%,修复BUG占了30%,在解决的这些BUG中,大部分都是代码级别的错误,使用
Chrome Devtools
基本都可以解决,但其中有三个比较神奇,算得上是灵异事件了。
鬼打墙
有一次后端同学重构了一下
DSP
广告平台的接口,让
Java
服务化提供接口,
PHP
做
web
控制层掌管路由和透传接口,于是对之前的接口URL重新规划统一了一下,内测没问题后就高高兴兴上线了,然而没过多久就有商家上报说页面报错没数据,于是我赶紧复现,但怎么都复现不出来,然后问商家浏览器是不是版本太低,网络是不是不稳定之类的,但商家的浏览器和网络环境都没问题,这就纳闷了,于是果断找了一台
Windows
机器(因为我们都是Mac而且没装虚拟机),让商家加
QQ
远程协助看一下到底报了什么错,倒腾了半天,连上商家电脑,复现果然报错了
NetWork Error
,打开
Chrome Devtools
一查,
ajax
请求居然没没发出去。看了一眼浏览器上那一排插件,怀疑是不是插件搞的鬼,发现居然有屏蔽广告的插件,大哥,你特么自己都在我们平台上投广告,你还装屏蔽广告插件。果断让他关闭这个插件,然后果然没问题。原来我们的接口URL里有
advertisement
这个单词,插件直接屏蔽了这个URL。没过多久,又有一个商家报页面没数据,呵呵,我们直接叫他关闭浏览器屏蔽广告插件,结果商家告诉我还是不行。?,还是远程协助查一下,发现开了隐身窗口,接口还是没返回数据,看到商家电脑右下角运行的系统杀毒软件,眉头一皱,难道是这货搞的鬼?打开设置一看,赫然有屏蔽广告这个选项。果然国产软件都流氓,你这所有的浏览记录都被人家知道了啊。第二天果断把
advertisement
改成
gg(guanggao)
,整个世界都清净了。
断头鬼
过了一段时间,我司搭了一个前端错误监控平台,可以收集客户端错误,上报到这个平台然后邮件告警开发者。收集的信息包括用户操作系统、浏览器版本、
IP
、操作路径等,这样就不需要再用
Windows
远程了。某一天,告警平台发邮件报错,店铺选择页面
js
运行报错,那还得了,选择不了店铺,相当于我们的后台入口挂了啊。果断按照报错的操作路径操作一次,又没复现。再一看操作系统与浏览器版本,找了一个一模一样的环境,还是复现不出来。晕了,还是用远程协助吧。商家那里确实有
js
运行报错,由于线上
js
也没有
source map
,压缩的代码也看不懂,查半天也没查出什么东西。回到监控平台后台,反复比对各条报错。结果发现
IP
都是差不多的范围,一查都是合肥电信的运营商,难道所有合肥电信的用户加载的这个
js
有问题?然后报给运维同学,他把那个
js
下载下来一看,长度不一样,和正常的版本比,少了一小段。肯定是
cdn
同步的时候,出了故障,果断把锅丢给七牛。
替死鬼
前几天,有一次发布后,一直收到邮件告警某个
base
的
js
运行报错,涉及的浏览器版本都是
Chrome 31到37
,轻车熟路开虚拟机复现,找半天找了一个
Chrome 31
,确实报错了,然而报错内容看不懂。想着那天发布内容包括升级基础
react
组件,加了一个
babel runtime
,还有一些其他的改动,难道是这些问题引起的?
然后尝试想让虚拟机
Chrome
运行本地代码,于是在
win
里面装
node
、
git
、下载仓库、打包、把线上代码代理到本地。结果
node-modules
都装不上去。然后再试试装
fiddler
抓包软件,把打包后的代码放在
win
里面,抓取那几个
js
,替换成打包后的本地代码,然而还是看不懂,只知道是一个基础函数,可能是
babel polyfill
的问题,于是尝试把前端仓库那几天的改成一一
revert
,看看到底是哪个改动导致的问题。结果回退到发布之前都还是报错,这就尴尬了,至此我已经花了一天时间去排查这个问题,期间让几个同事一起排查也没发现问题本源。
最后想着把
win
的网络设置成
Mac
一样的网络,把
win
浏览器使用
SwitchySharp
设置成
Mac
的代理,这样就可以在
win
里面使用
Mac
的开发环境,(其实就是在
Mac
起一个
node
服务,监听一个端口,在这个服务里把所有的线上的前端资源(
js
,
css
)替换成本地代码,本地这个服务相当于一个网关服务器,还可以把网址指向不同环境的服务器。)结果惊奇的发现在预发环境是没有问题的,只有线上环境才有报错。我的第一反应是难道后端改造了什么数据类型?把线上数据和预发环境数据比对一下,然而一模一样。这个时候,对比两个环境只有两个差异了,一个线上环境多一个统计日志上报的
js
,还有一个就是错误收集上报的
js
,问了一下这两个
js
的维护者,果然统计日志的js,在那次发布的时候改动了,为了使用
Object.assign
,加了一个
polyfill
,然后和
base js
里面的
polyfill
冲突了,由于统计日志的
js
先加载,所以报错是在
base js
里面。
这个问题比较难排查的地方是:
- 复现环境比较苛刻
- 后端仓库的改动(统计日志的
js
)和前端仓库产生了关联,版本回退难以排查
- 产生问题的
js
并不是出现报错的 js
总结
出现BUG在所难免,代码逻辑、浏览器兼容性、网络故障等等都会导致一些意想不到的问题,遇到问题首先不要慌,解决问题要有方法论,先把问题复现出来,然后使用
Chrome Devtools
,设置断点,观察数据条件,基本可以找出代码错误,其他问题,可以类似高中生物实验,结合条件对照,找出差异的条件,定位到问题,这个过程中需要敏锐的观察力。