Error Handling
解决什么问题:异常不是 bug,是系统的合法运行状态——好的错误处理让系统在异常态下仍可观测、可恢复、可继续控制。
它是什么
Error Handling(错误处理) 是系统面对预期外的状态变化时的应对机制。它不是"try-catch 包起来"那么简单,而是分层策略:
- 错误检测——哪里是边界(验证、断言、监控)
- 错误传播——异常如何向上传(异常/返回值/事件)
- 错误恢复——能否自动重试、降级、回滚
- 错误观测——外部能否感知(监控、告警、日志)
SE@G Ch 8:"A program that doesn't handle errors gracefully is a program that will fail at scale."
V2 视角(V2.7 B5 反馈):错误处理是"反馈通道"。控制论把错误视为受扰动后状态的偏差——观测器发现偏差,控制器做出修正。错误处理 = 工程化的反馈通道。
关键属性
| 属性 | 值/含义 |
|---|---|
| 三层划分 | 业务错误(领域) / 系统错误(基础设施) / 用户错误(输入) |
| 传播方式 | 异常(throw)/ 返回值(Result)/ 事件(Domain Event) |
| 恢复策略 | 重试 / 降级 / 熔断 / 补偿 |
| 观测要求 | 每种错误必须可观测(日志 + 指标 + trace) |
| 核心约束 | 错误是状态,不是异常——业务上"余额不足"是状态 |
| 反模式 | catch(Exception) 吞掉所有 / 用异常做流程控制 |
| 判错标准 | 系统出问题时能否 30 秒内定位到根因 |
怎么用
场景 1:领域层错误处理
原则:领域层不抛技术异常——抛领域错误或返回 Result。
java
// 错:用 NullPointerException 做业务控制
public void transfer(Account from, Account to, Money amount) {
if (from.balance().lessThan(amount)) {
throw new RuntimeException("余额不足"); // 错
}
}
// 对:业务错误 = 领域状态
public Result<Transfer> transfer(Account from, Account to, Money amount) {
if (from.balance().lessThan(amount)) {
return Result.failure(DomainError.InsufficientBalance); // 对
}
// ...
return Result.success(transfer);
}场景 2:基础设施错误处理
基础设施错误(DB 断连、网络超时)→ 重试 + 熔断 + 降级:
java
// 用 resilience4j 或类似
@Retry(maxAttempts = 3)
@CircuitBreaker(failureRateThreshold = 50)
@Fallback(method = "fallbackQuery")
public List<Order> queryOrders() { ... }关键:基础设施错误不要冒泡到领域层——边界翻译(IDDD Ch 13)。
场景 3:用户输入错误
原则:用户错误 = 400 + 具体原因——告诉用户"怎么改":
json
{ "error": "INVALID_EMAIL",
"message": "邮箱格式不合法",
"field": "email" }不是 "Invalid request"——这是 SE@G Ch 8 强调的"actionable error"。
常见误区
- "异常 = 错误"——错。异常是机制,错误是事实。流程控制用 if 不用 catch
- "catch(Exception)"——错。SE@G Ch 8 反对:吞掉异常 = 隐藏问题 = 后期调试噩梦
- "错误处理 = 防御性编程"——错。业务核心要"信任",边界要"防御"。全防御 = 复杂度爆炸
- "领域层抛技术异常"——错。IDDD Ch 5:领域层只表达业务事实
- "错误日志足够"——错。日志是被动观测,指标是主动监控——错误必须有 metric counter
关键洞察
错误处理是控制论反馈通道的工程实现——错误 = 偏差,处理 = 修正。
控制论视角:任何控制系统都建模"误差"(e = y_ref - y)。软件系统的"误差" 就是错误。 IDDD Ch 5 视角:领域错误是领域模型的一部分——它和业务实体同等重要。 SE@G Ch 8 视角:错误处理是规模化前提——单机能跑 ≠ 系统稳定。 EDM Ch 7 视角:异步系统的错误 = 死信队列 + 重试 + 补偿 + 监控四件套。
相关链接
- Coding Convention——错误命名约定
- Log Metric Trace——错误的观测通道
- V3 涌现之时——错误处理策略随系统演化
- V3 涌现作为——错误 = 反馈通道
- 源典:IDDD Ch 5——领域错误 vs 技术异常
- 源典:SE@G Ch 8——规模化错误处理