48 — Cause and the complete failure model
In v4, Cause<E> contains a flat reasons array. Each reason is a typed Fail, a defect (Die), or an Interrupt. Use Cause.findErrorOption, Cause.hasFails, Cause.hasDies, and Cause.hasInterruptsOnly rather than matching a recursive tree.
Most feature code handles typed errors with Effect.catch or catchTag. Use Effect.catchCause at an operational boundary that genuinely needs defects and interruption too.
The full test suite
The index.test.ts for this lesson, verbatim from steps/48-cause-and-sandbox/.
import { describe, expect, it } from "vite-plus/test"import { Cause, Effect, Exit, Option } from "effect"
describe("Cause", () => { it("stores typed failures, defects, and interruption as flat reasons", () => { const exit = Effect.runSyncExit(Effect.fail("typed")) expect(Exit.isFailure(exit)).toBe(true) if (Exit.isFailure(exit)) { expect(Cause.hasFails(exit.cause)).toBe(true) expect(Option.getOrThrow(Cause.findErrorOption(exit.cause))).toBe("typed") expect(exit.cause.reasons).toHaveLength(1) } })
it("uses catchCause only at a boundary that needs the full failure model", () => { const label = Effect.die("defect").pipe( Effect.catchCause((cause) => Effect.succeed(Cause.hasDies(cause) ? "defect" : "failure")), ) expect(Effect.runSync(label)).toBe("defect") })})