The Architect’s Notebook · 2026-01-15

为什么异常处理会搞垮你的系统

摘要

本文从系统设计角度分析了异常处理的重要性。作者指出大多数开发者对异常处理的理解存在误区,仅仅将其视为代码语法问题,而忽略了其作为系统故障沟通机制的本质。文章详细列举了六个常见错误,包括丢失根本原因、捕获所有异常、吞噬异常、错误重抛、未使用异常过滤器以及自定义异常缺少上下文。作者通过真实案例展示了这些错误如何导致生产环境问题,并提供了具体的最佳实践。

内容框架与概述

文章首先阐述了异常处理的系统设计意义,指出良好的异常设计能让故障可预测、日志有意义、系统能优雅恢复,而糟糕的设计则会导致静默失败、混乱日志和级联停机。作者强调异常处理不只是语法问题,而是系统各层之间传递失败信息的沟通机制。

接下来作者详细分析了六个常见错误。第一个错误是丢失根本原因,开发者经常错误地传递InnerException而丢弃原始异常,导致调试困难。第二个错误是捕获所有异常,这会吞噬包括OutOfMemoryException在内的不可恢复错误,作者建议只捕获能够处理或恢复的异常类型。

第三个错误是吞噬异常,即捕获后不记录也不处理,这会隐藏真正的问题直到演变成生产事故。第四个错误是错误重抛,使用throw ex会重置堆栈跟踪,而使用throw才能保留原始调用栈。第五个错误是没有使用异常过滤器,when子句可以在不展开堆栈的情况下进行条件判断。第六个错误是自定义异常缺少上下文信息,添加事务ID、金额等属性能显著提升可观测性。

核心概念及解读

有意义的异常类型:不要抛出通用的System.Exception,而应使用InvalidOperationException、ArgumentException等具体类型,或创建包含领域上下文的自定义异常类。

异常链保护:在捕获并重新抛出异常时,必须将原始异常作为innerException传递,形成完整的异常链,保留故障的完整上下文和历史。

选择性捕获:只捕获你能够处理或从中恢复的异常类型,对于OutOfMemoryException等致命异常应让其冒泡到更高层,避免静默失败。

堆栈跟踪保留:使用throw而非throw ex来重新抛出异常,这样能保留原始堆栈跟踪信息,对调试至关重要。

异常上下文增强:自定义异常应包含事务ID、处理步骤、金额等关键业务信息,这样当异常到达监控系统时可以进行聚合分析和问题定位。


原文信息

字段内容
原文Ep #73:Why Your Exception Handling is Killing Your System (And How to Fix It)
作者The Architect’s Notebook
发表日期2026-01-15

此摘要卡片由 AI 自动生成