大厂规范严禁在catch块中仅打印异常而不做实质处理,因其掩盖异常类型与根因、破坏异常传播链、导致日志缺乏上下文、违反可观测性底线;正确做法是用slf4j记录带traceid等上下文的error日志,并明确后续动作。

大厂规范严禁在 catch 块中只写打印(比如 e.printStackTrace() 或 System.out.println("出错了"))而不做实质处理,核心原因不是“没报错”,而是这种写法让异常既没被解决、也没被正确传递、更没被可观测——它把一个明确的故障信号,强行降级成一条模糊的日志碎片。
掩盖真实异常类型和根因
只打印堆栈或简单字符串,无法区分异常性质:
-
NullPointerException可能是代码逻辑缺陷,需修复 -
TimeoutException可能是网络抖动,适合重试 -
SQLException可能是数据库连接池耗尽,需扩容或熔断 -
IllegalArgumentException往往是上游参数错误,应拦截并返回明确提示
笼统打印后,所有这些都混在日志里,运维或开发看到的只是“某处抛了异常”,却无法判断该告警、该降级、该回滚,还是该联系第三方。
破坏异常传播链与分层决策能力
异常的价值在于它能向上冒泡,触发不同层级的响应策略:
- DAO 层捕获 SQL 异常 → 记录并转为
DataAccessException - Service 层识别业务语义 → 决定是否重试、补偿或抛
BusinessException - Controller 层统一拦截 → 返回 HTTP 状态码 + 用户友好文案
如果在中间层只打印就完事,异常就“断”在这里:上层收不到信号,无法执行降级逻辑;监控系统收不到指标,错误率统计失真;链路追踪里也看不到失败标记,整个调用链呈现“成功假象”。
日志缺乏上下文,排障效率归零
e.printStackTrace() 只输出堆栈,不带任何业务标识:
- 没有
traceId,无法关联上下游请求 - 没有
userId或orderId,无法定位影响范围 - 没有操作描述(如“更新用户手机号时校验失败”),无法快速理解场景
结果就是:线上出问题,翻一小时日志,最后靠猜;SRE 收到告警,查不出是偶发还是蔓延;新同学接手代码,以为“这里早就处理好了”,不敢动相关逻辑。
违反可观测性与防御性编程底线
大厂生产环境依赖三要素:日志、指标、链路。空有打印、无结构化记录、无分类决策、无后续动作,等于主动关闭了其中两扇门。
- 静态扫描工具(SonarQube/Checkstyle)会直接标为 Blocker 级别缺陷
- Code Review 中一旦出现,会被打回并要求说明“为何不记录上下文?为何不重试/降级/上报?”
- 面试官看 GitHub 项目,一行
e.printStackTrace()就足以判定“缺乏生产环境敬畏心”
真正合规的做法是:用 SLF4J 记录带上下文的 error 日志,明确后续动作(重试/返回默认值/抛封装异常),必要时触发告警。打印,只是起点,不是终点。











