程序员老鬼

上周code review的时候,发现一个同事把所有异常都用try-catch包起来,然后就ignore了。这种代码怎么能上线?

哎我跟你说,上周五晚上我们组 code review,差点没气笑了。一个同事写的服务层代码,基本上是这样子的:

try {
// 一大坨业务逻辑
} catch (Exception e) {
// ignore
}

真的就是 ignore 啊,连个 e.printStackTrace() 都没有,日志也不打。你说这种代码上线了,哪天线上出问题了,鬼才知道是啥原因。到时候领导追责,还不是背锅背到我们头上。

Image

异常不是垃圾桶

其实很多新人有个误区,他觉得 try-catch 是个“保险箱”,能保证程序不挂掉,于是就干脆所有异常都吞掉。这就像你家厨房着火了,你把报警器电池拔掉,心想“反正没人吵闹”,那火就自动灭了吗?显然不会。异常被无脑吞掉,问题就被掩盖了,后果就是线上排查困难。

你想啊,正常写法我们至少要有日志记录:

try {
    doSomething();
} catch (IOException e) {
    log.error("文件读取失败", e);
throw e; // 或者转换成业务异常抛出去
}

这样即便出问题,日志里能搜到栈信息,定位快得多。可要是啥都没有,线上现象就是“用户点了按钮没反应”,那真的是查一天也查不出个结果。

你应该怎么写

我一般会跟新人说,异常处理要分三层来考虑:

  1. 能解决的就地解决比如你读文件发现路径不存在,可以给个默认值继续跑。

  2. 不能解决的往上抛交给调用者,或者全局异常处理器兜底。

  3. 日志必须打至少要知道什么时候、什么地方、什么线程出了问题。

像 Spring Boot 里面常用的 @ControllerAdvice 搭配 @ExceptionHandler,就能统一兜底。这样你在业务里不用每个方法都乱 try-catch,一旦发生异常,全局处理器能统一输出格式化的错误日志。

举个反例

你们见过这种反人类写法没?

public String getData(){
try {
return repository.find();
    } catch (Exception e) {
returnnull;
    }
}

看似优雅,结果调用方拿到 null,一不小心就 NullPointerException。到时候谁还记得这个 null 是你“善意”返回的?

线上排查多难受

我有次在公司楼下抽烟,小李跑过来喊我,说某个接口总是返回空数据,日志一点异常也没有。后来 debug 半天,才发现就是有人把 SQLException 给吞了,导致数据库查不出来结果,接口就返回空集合。你说这种锅,浪费多少人力排查。

更坑的是,有时候异常吞掉还会影响事务。比如你在 Spring 里这样写:

@Transactional
publicvoidsaveUser(User user){
try {
        userDao.save(user);
    } catch (Exception e) {
// ignore
    }
}

结果 save 失败了,事务照样提交,外层完全不知道。后果就是脏数据进库,等排查到数据库层的时候,已经晚了。

怎么化解这种代码

那遇到同事写这种代码咋办?我一般建议几步:

  • code review 直接怼,告诉他吞异常等于埋雷。
  • 引导用日志框架,比如 slf4j + logback,强制规范日志级别。
  • 做静态代码检查,SonarQube 里可以配置规则,禁止空 catch。
  • 写文档和规范,团队约定:catch 到异常必须处理或抛出,不允许无脑吞。

其实很多问题,不是技术不会,而是习惯不好。写代码不想“多此一举”,结果害死的是后面的维护人。

异常处理这东西,说难不难,但真要做到位需要点“敬畏心”。代码不是写给自己跑的,是给线上系统扛流量的。你以为少写一行日志很爽,等凌晨两点接到报警电话的时候,你就知道吞掉的不是异常,是你自己的睡眠。

兄弟们,你们组是不是也有这种喜欢乱 try-catch 的?你们都是怎么劝的?我这边有时候真想在 review 的时候直接在评论里写:“哥们,你这代码等于放了个定时炸弹。”

要不然这样,下次我给你们整理一个“异常处理最佳实践”的 demo 项目?里面把常见场景都走一遍,顺便写几个正确的 catch 样例。这样拉着新人一起改代码,比单纯说教管用多了。

-END-

我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html

最后给大家分享一份不错的副业资料,点击下方公众号,回复关键字: 副业 领取,也可以链接我领取,微信:hls404