跳到主要内容

被一个 NPE 卡了三天,原因蠢到我不想说

敏姐转开发
敏姐转开发

· 阅读约 3 分钟

上周三到周五,三天,我基本都在跟一个空指针搏斗。一个我自己写的空指针。

先说背景(不说背景我心里不踏实):我们内部有个对账小工具,里面有个导出任务,定时跑,每天早上七点出文件。这是我转开发之后接的第一个带定时逻辑的东西,八月底才交接过来,我自己觉得已经摸熟了。

周三早上一来,群里说昨天的对账文件没出。我翻日志,500,NPE,堆栈指到 ExportTaskBuilder 第 87 行。

然后就是三天的拉锯。

第一件让我绕远的事是它偶发。本地跑通,测试环境有时候通有时候不通,重跑一次可能就好了。按我做测试的习惯,第一步是收敛复现条件。我列了几组:数据量大小、有没有跨天、是不是某类商户的数据、跑的时候有没有别人在同一张表上写。大概八九组吧,交叉着试。结论是跟这些都没关系——也可能有关系,概率太低我看不出来,这里我可能想复杂了。

第二件事是我一开始不信堆栈。第 87 行那行代码我看过好几遍,它不可能空,至少我以为不可能。所以我跑去看上游:缓存加载的顺序、凌晨那个刷数据的任务有没有跑完、导出用的查询是不是走了从库(走从库就有时序问题)。全都排了一遍,全都正常。

周四晚上我换了个笨办法,一行行往上翻 diff。翻到 87 行我才发现,那行不是业务代码。

是我自己上周加的日志。

上周我排查另一个导出少字段的问题,在循环里加了一行 log.info("export rule: {}", context.getRule().getName());。rule 这个字段,在没命中任何规则的那批数据上是 null。也就是说,我为了看清楚问题加的那行日志,本身会在另一批数据上抛异常。日志打在循环里,一条挂掉整个任务就结束了,一份文件都出不来。

所以真实情况是:我上周四加了那行日志,上周五开始,每天早七点都挂。而我一直在本地拿"有规则"的那批数据测,本地永远是绿的。

周五上午删了,改成空判断加个占位符。跑,文件出来了。就这样,两分钟的事。

我事后想了下,这不算技术问题。日志也是代码,它也有边界,这个我做测试的时候天天说,转到开发反而忘了。有点好笑也不好笑。

还有件事想记一下:那三天我有两次想去问开发同事,都忍住了,觉得是自己的锅不好意思张口。现在看应该早点问。不过我也不敢说下次就一定问得出口,性格这东西改起来慢。

先这样吧,等下还得去看那个刷数据的任务,我有点担心它也在某个我没覆盖到的边界上挂着。想到再补。

敏姐转开发
敏姐转开发

测试八年,转开发第一年。慢一点没关系,返工最贵。

查看主页 →