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. 1

    为什么Error也必须成为可组合Data

    Exception适合unexpected fault和跨层unwind,但routine validation、not-found、business rejection若全靠throw/catch,signature隐藏outcomes,caller也难以组合。Functional error h…

  2. 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. 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右侧一定是成功业务状态吗。答案都是否。

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));
分步1 / 3

切换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);
分步1 / 3

切换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自动决定。

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)));
分步1 / 3

切换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

  1. Outcome taxonomy先区分absence、validation、business rejection与unexpected fault。
  2. Either Map/Bind只推进Right,Left short-circuit dependent work。
  3. Independent validation可accumulate,dependent validation必须有序。
  4. Delivery boundary稳定翻译domain outcome,不泄露internal cause。
  5. 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通过类型表达允许的输入、成功结果和失败分支;类型只编码已声明的不变量,不能替代运行时校验。应准备能编译与必须被拒绝的调用案例,并以成功、空值/缺失和业务失败样本核对每个分支都被显式处理。

讨论

评论区加载中…