Effect 深度课effect@4.1.4 · LTS
错误与诊断

L09 两类错误:failure 与 defect

⏱ 25 min难度 2/5前置:L08
本课目标
  • 能判断一个失败该建模成哪种
  • 知道各自的处理入口
前置课时尚未完成:L08

可以自行跳转学习,但按顺序推进会更省力;学情分析会把这类缺口归入「前置缺口」。

分界线是「要不要做决策」

预期错误(failure / typed error)属于业务领域:无效输入、记录不存在、请求被拒。它们出现在 E 里,调用方用 Effect.catch / catchTag 恢复。缺陷(defect)代表断言失败、不可能状态、第三方 bug,不进 E,运行时仍由 Cause 完整保留。

两条处理路径
← 代码可左右滑动 →
import { Effect } from "effect"

const domain = Effect.fail(new NotFound()).pipe(
  Effect.catchTag("NotFound", () => Effect.succeed(null))
)

// 缺陷只在边界处检查 / 上报
const boundary = risky.pipe(
  Effect.catchDefect((defect) =>
    Effect.log("unexpected: " + String(defect))
  )
)

// 想看全貌:把整个 Cause 暴露出来
const full = Effect.catchCause(risky, (cause) => report(cause))
💡 catch* 系列只处理 E 通道;要看 defect 与 interruption 必须用 catchDefect / catchCause / Effect.exit。
⚠️ 不要在领域逻辑里吞掉缺陷

把 defect 统一 catch 成「返回默认值」会掩盖 bug。正确做法是让它在应用边界被记录、告警、转成 500,而不是变成一条正常的业务分支。

交互演练
关键术语
failure
E 通道里的预期错误
defect
Cause 里的意外错误,不参与类型化恢复
常见误区
× 把「不可能发生」的状态用 Effect.fail 建模,逼调用方写永远用不上的恢复分支。
随堂测验(即时反馈,答题计入掌握度)
Q1「用户余额不足」应建模为?
Q2哪个算子能看到缺陷和中断?