Chapter 6. Functional error handling
覆盖typed outcomes、failure chaining、Either validation、client translation与Either variants,区分absence、validation、business rejection和unexpected fault。
学习目标
- 能区分Option、Either/Result、Validation与exception适用的absence/failure contract,保留必要诊断
- 能推导Right/Left上的Map、Bind与recovery flow,复现dependent operation的short-circuit
- 能设计fail-fast与error accumulation validation,并把domain error稳定翻译为client response
机制总览
Chapter 6. Functional error handling:机制路径
- 1
为什么Error也必须成为可组合Data
Exception适合unexpected fault和跨层unwind,但routine validation、not-found、business rejection若全靠throw/catch,signature隐藏outcomes,caller也难以组合。Functional error h…
- 2
A safer way to represent outc…
Option表示routine absence,Either/Result表示typed expected failure或success,Validation可积累independent errors;unexpected DB outage、bug或invariant corruption通常保…
- 3
Chaining operations that may …
Either的Right承载success,Left承载error。Map只转换Right;Bind接收 T - Either 并在Left short-circuit。Later operation只在前置依赖成功时运行,避免每步if/return。Recovery必须显式,不能用宽泛default吞error。
章级决策实验
Chapter 6. Functional error handling:机制与证据
切换《Chapter 6. Functional error handling》的三个关键教学阶段,先解释机制,再用运行与失败证据验证结论。
选择推理阶段
当前阶段 · 为什么Error也必须成为可组合Data
Exception适合unexpected fault和跨层unwind,但routine validation、not-found、business rejection若全靠throw/catch,signature隐藏outcomes,caller也难以组合。Functional error h…
可核验证据
以确定输入重复运行「为什么Error也必须成为可组合Data」的最小管线,用属性测试、状态快照和副作用调用轨迹核对返回值、失败传播与资源边界。
学完《Chapter 6. Functional error handling》后,应能从输入和前置条件推导状态变化,并用可重复的构建、运行或边界测试证明结果。
失效—证据矩阵
Chapter 6. Functional error handling:失效与核验
为什么Error也必须成为可组合Data
典型失效
若把「为什么Error也必须成为可组合Data」只写成函数式术语而不隔离副作用、状态和失败分支,组合后的程序仍会依赖隐藏时序,无法从输入稳定推导结果。
核验证据
以确定输入重复运行「为什么Error也必须成为可组合Data」的最小管线,用属性测试、状态快照和副作用调用轨迹核对返回值、失败传播与资源边界。
A safer way to represent outc…
典型失效
若把「A safer way to represent outc…」只写成函数式术语而不隔离副作用、状态和失败分支,组合后的程序仍会依赖隐藏时序,无法从输入稳定推导结果。
核验证据
以确定输入重复运行「A safer way to represent outc…」的最小管线,用属性测试、状态快照和副作用调用轨迹核对返回值、失败传播与资源边界。
Chaining operations that may …
典型失效
若把「Chaining operations that may …」只写成函数式术语而不隔离副作用、状态和失败分支,组合后的程序仍会依赖隐藏时序,无法从输入稳定推导结果。
核验证据
以确定输入重复运行「Chaining operations that may …」的最小管线,用属性测试、状态快照和副作用调用轨迹核对返回值、失败传播与资源边界。
为什么Error也必须成为可组合Data
Exception适合unexpected fault和跨层unwind,但routine validation、not-found、business rejection若全靠throw/catch,signature隐藏outcomes,caller也难以组合。Functional error handling把expected outcomes放进return type,让success/failure沿同一data flow移动。
先预测:所有exception都应变Left吗;Option和Either只差error message吗;validation fields应总fail-fast吗;catch后转500是否保留domain contract;Either右侧一定是成功业务状态吗。答案都是否。
↡以return value显式表示success、absence或expected failure,使caller在type-guided flow中处理。A safer way to represent outcomes
Option表示routine absence,Either/Result表示typed expected failure或success,Validation可积累independent errors;unexpected DB outage、bug或invariant corruption通常保留exception/cause到recovery boundary。Taxonomy决定retry、status、logging owner,不能只按“会不会失败”选择wrapper。
Either<Error, Customer> Validate(CustomerDto dto) =>
EmailAddress.Parse(dto.Email)
.Map(email => new Customer(email));切换Option、Either、Validation与exception
Chaining operations that may fail
Either的Right承载success,Left承载error。Map只转换Right;Bind接收T -> Either<Error,R>并在Left short-circuit。Later operation只在前置依赖成功时运行,避免每步if/return。Recovery必须显式,不能用宽泛default吞error。
Either<Error, Receipt> result =
Parse(request)
.Bind(Validate)
.Bind(Reserve)
.Bind(Charge);切换Right、Left、Map与Recover
Validation: a perfect use case for Either
Dependent validation需Bind fail-fast,例如只有parse出Date后才能检查range;independent fields可Apply/Validation accumulation,一次返回email、name、age全部错误。Either默认常是one Left/one Right,是否积累取决于error semigroup/combinator,不是type name自动决定。
↡多个independent checks都执行并以定义的combine规则收集全部errors的validation语义。Representing outcomes to client applications
Delivery boundary把domain errors映射HTTP/problem details、UI message或CLI exit code。Mapping应stable且不泄露stack/secrets;internal log保留correlation与cause。Business conflict可能409,invalid input 400,not-found 404,dependency fault 503/500,具体由API contract决定。
return result.Match(
Left: error => Problem(error.Code, error.Message, ToStatus(error)),
Right: value => Ok(ToDto(value)));切换fail-fast、accumulate、HTTP与unexpected
Variations on the Either theme
Result、Exceptional、Validation、Try等variants调整error type、accumulation、laziness或exception capture。选型按domain states和composition需求,不按命名。Library boundary最好统一少数canonical types,adapter负责第三方差异。
Compatibility and observability gate
Public outcome一旦被client消费,error code、status、field path与retryable就是versioned contract;内部更换Either实现或异常库不能顺手改变它。发布前建立consumer matrix,逐项验证旧client、unknown code fallback、message redaction和cancellation的独立映射。Metrics按stable code聚合,secure log保留cause chain与correlation id,trace标记failure stage但不复制secret。这样expected rejection、client cancellation与unexpected fault既能分别告警,也不会因翻译层升级破坏调用者。
本章回顾:Expected Failure走Data,Unexpected Fault保留Cause
- Outcome taxonomy先区分absence、validation、business rejection与unexpected fault。
- Either Map/Bind只推进Right,Left short-circuit dependent work。
- Independent validation可accumulate,dependent validation必须有序。
- Delivery boundary稳定翻译domain outcome,不泄露internal cause。
- Variant type必须对应真实error semantics,不能用一个Left吞所有世界。
练习
问题 1:登录密码错误、用户不存在和数据库超时分别如何表示?
问题 2:表单validation何时accumulate、何时Bind?
问题 3:怎样避免Either pipeline吞掉unexpected exception?
术语表
名词解释
本章出现的专业名词,用大白话再讲一遍。
- typed outcome channel
- failure taxonomy
- left short-circuit
- validation accumulation
- outcome translation boundary
原版目录概念补充核对
以下条目补齐官方目录中容易被示例主线掩盖的概念。它们不重复罗列目录,而是明确每项概念的机制、适用边界和验收证据。
Chaining operations that may fail:机制、边界与证据
Chapter 6. Functional error handling中的Chaining operations that may fail应写成可组合的输入—输出契约,并把环境读取、状态改变与失败显式放在边界。用确定输入运行正常、空值和失败样本,同时记录返回值与副作用轨迹,证明结论不依赖隐藏状态。
Validation: a perfect use case for Either:机制、边界与证据
Chapter 6. Functional error handling中的Validation: a perfect use case for Either通过类型表达允许的输入、成功结果和失败分支;类型只编码已声明的不变量,不能替代运行时校验。应准备能编译与必须被拒绝的调用案例,并以成功、空值/缺失和业务失败样本核对每个分支都被显式处理。
Representing outcomes to client applications:机制、边界与证据
Chapter 6. Functional error handling中的Representing outcomes to client applications应写成可组合的输入—输出契约,并把环境读取、状态改变与失败显式放在边界。用确定输入运行正常、空值和失败样本,同时记录返回值与副作用轨迹,证明结论不依赖隐藏状态。
Variations on the Either theme:机制、边界与证据
Chapter 6. Functional error handling中的Variations on the Either theme通过类型表达允许的输入、成功结果和失败分支;类型只编码已声明的不变量,不能替代运行时校验。应准备能编译与必须被拒绝的调用案例,并以成功、空值/缺失和业务失败样本核对每个分支都被显式处理。