读一套 7×24 运行的工控软件时,一个数字一直让我不舒服:34 处空 catch。就是 catch {} 里面什么都不写的那种。
我第一次数出来的时候,以为是我 grep 姿势不对,又数了一遍,还是 34。分布在通信层、数据库层、算法层、UI 层。
一个异常被吞掉的时候,问题没有消失,它只是不再出声。程序带着这个隐患继续跑,结果要么更错,要么在更远的地方以更奇怪的样子炸出来。
最要命的是现场的人只看到结果不对,日志里却什么都没有。你连错在哪一行都不知道,怎么复现。那些复现不了的玄学故障,很多就是被空 catch 把证据埋了。
少数情况可以静默。幂等的清理动作,比如重复 Dispose、重复关闭连接,抛了也无害;明确预期会失败、失败也无所谓的探测,比如探测某个可选设备是否存在。但即使这些情况,也建议至少留一行级别低的日志,因为无害是当下的判断,设备换了它可能就有害了。
我现在写 catch,要么真的记一笔日志,哪怕级别低,要么用 throw; 把问题交上去,绝不让它悄无声息地死在我这一层。那种包住就安全的错觉,是用一次次复现不了的现场故障换来的。
接手任何老系统,我第一件事不是看它能跑,而是数它的空 catch。空 catch 多的系统,就像一栋墙上全糊着胶布的房子,你不知道底下补的是裂缝还是窟窿,但你知道,这房子主人选的是别让我看见,而不是修好它。