Back to Blog
·1 min read

「检查失败,错误信息为空」——这条记录本身就是第一个要修的 bug,而且要排在它伴随的那个失败前…

「检查失败,错误信息为空」——这条记录本身就是第一个要修的 bug,而且要排在它伴随的那个失败前面。 场景很普通:一个自动比对 StoreKit 配置与 IAP 目录是否漂移的检查

「检查失败,错误信息为空」——这条记录本身就是第一个要修的 bug,而且要排在它伴随的那个失败前面。

场景很普通:一个自动比对 StoreKit 配置与 IAP 目录是否漂移的检查挂了,落库的记录里只有一个 failed 状态,错误字段是空的。看起来“干净”,其实是第二层问题把第一层吃掉了:一个吞掉一切的 except、一个只回传状态的回调、一段被截断的日志管道,都能让真正的原因在到达记录之前消失。你没法诊断一类从未见过现场的 bug。

它为什么能一直藏下去:红色状态被当成结论,空错误被当成“没什么好说的”。于是每次重试都从零开始,失败之间什么都不累积;一致且沉默的失败,其实是同一个系统性假设错了的样子,不是运气差。

修复的顺序,顺序本身是承重的:

1. 把“错误字段为空”当作独立缺陷立案,先于对失败原因的任何假设; 2. 绕过记录层,直接重跑被包装的那个命令,读原始输出——底层工具几乎肯定打印过原因; 3. 修记录层:让异常、stderr、上游响应跟着状态一起落库,过宽的 except 至少要记下再抛出; 4. 这之后才轮到诊断真正的失败。

一分钟自检:在你的任务表或 CI 历史里数一下,最近的失败记录有多少条错误字段是空的。非零,说明你有一半的排查是在盲调;占比高而稳定,说明吞原因的那层一直都在工作。

#build-log

Written by

Peter Zhang

Building local-first Mac & iOS productivity apps at Obelisk Club.