Skip to content

docs: add tutorial for error modeling - #1523

Open
f15u wants to merge 74 commits into
mainfrom
tutorial/error-modeling
Open

f15u wants to merge 74 commits into
mainfrom
tutorial/error-modeling

Conversation

@f15u

@f15u f15u commented Sep 3, 2026

Copy link
Copy Markdown
Member

No description provided.

@f15u
f15u force-pushed the tutorial/error-modeling branch 3 times, most recently from 7839fe3 to a161be1 Compare September 4, 2026 20:26
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

Cloudflare Preview

URL: https://effectwebsite-websiteworker-pr-1523-uk4tiolkxbarmaut.matechs.workers.dev

Built from commit bade585.


This comment updates automatically with each deployment.

@f15u
f15u force-pushed the tutorial/error-modeling branch 10 times, most recently from ff45dfb to cc3caf0 Compare September 10, 2026 01:18
@f15u
f15u marked this pull request as ready for review September 10, 2026 01:19
@f15u
f15u force-pushed the tutorial/error-modeling branch 5 times, most recently from 52da0ee to 4256858 Compare September 13, 2026 00:09
@f15u
f15u force-pushed the tutorial/error-modeling branch 3 times, most recently from 83e72df to 24b3672 Compare September 16, 2026 23:46
gcanti and others added 29 commits September 17, 2026 02:13
The pronoun 'this' had no clear referent after the signature example. Naming the absent errors and their effect on processPayment gives the following list a concrete cause instead of making readers reconstruct the connection.
The word 'error' was ambiguous outside the code block and could be mistaken for an error class or type. Referring to catch (error) ties the explanation to the caught value and makes the meaning of unknown explicit.
The four limitations have no required order and are not steps in a process. Bullets avoid implying a sequence or ranking, so readers can treat each item as a separate consequence of missing error types.
The previous wording did not say what was specified in excess and ended with an ambiguous 'it'. Naming the unnecessary handler in processPayment makes the label concrete and sets up a clear contrast with the under-specification case.
Describing the problem as forgetting an error focused on developer behavior rather than the incomplete handler set. Naming the omitted handler makes under-specification concrete and creates a direct contrast with the preceding over-specification case.
The previous wording described the result of a new error but did not identify what had drifted. Naming the handler set that falls out of sync distinguishes change over time from an already missing handler.
Repeated 1. markers rely on the renderer to supply the intended sequence and look incorrect in the Markdown source. Explicit numbers preserve the order for readers of the source and for renderers that do not normalize ordered lists.
The tutorial had just shown that a typical signature omits failure information, so claiming that signatures answer all three questions contradicted the example. Framing the list as information a caller needs preserves the gap that Effect will fill.
The direct jump from an imaginary throws clause to Effect asked readers unfamiliar with errors as values to accept a new model without an intermediate step. A concrete outcome union shows how plain TypeScript can expose failures, while the caller example explains why Effect's automatic propagation removes repetitive bookkeeping.
The tutorial moved from exposing failures in Effect's Error type parameter to defining tagged error classes without marking the change in purpose. A dedicated subsection makes that shift visible.

The old transition also left readers to infer why tags matter. Connecting the union to TypeScript's structural typing explains the risk of indistinguishable errors before presenting Data.TaggedError as the solution.
Leading with _tag exposed an implementation detail before readers knew why errors need to be distinguished. Starting from the caller's different recovery choices gives the unique identifier a concrete purpose, while moving _tag after the example lets the mechanism follow the motivation.

The structural typing detour and suffix convention are unnecessary for using Effect's idiomatic Data.TaggedError approach, so removing them keeps the tutorial on its error-modeling path.
Repeating the full payment implementation made readers search through unchanged code to find the relevant difference. Showing the original error classes beside their Data.TaggedError replacements keeps attention on why instanceof works at runtime while Effect needs distinct types in its error union.
The section explained the runtime and type-level distinction twice and introduced Data.TaggedError before showing the definitions it replaces. A single problem-to-solution sequence lets readers compare the two forms without holding earlier code in memory, while constructing an error verifies how its identifier becomes _tag.
The tutorial introduces expired card, invalid token, and network failure in that order, but later examples reshuffled them. Keeping the same sequence in definitions, unions, branches, and handlers lets readers recognize the recurring error set without remapping it at each step.
Rewriting the payment flow is the final step in making failures visible to TypeScript, not a separate phase of the tutorial. Nesting it under that section preserves the chapter hierarchy, while naming the full payment-flow rewrite matches the Promise comparison and both function refactors it contains.
The previous walkthrough centered Effect.gen and passed an authorization through processPayment unchanged, so readers had to absorb an artificial example before seeing why propagation matters. Use Effect.fn because it is the idiomatic reusable-function form and defines the generator function once instead of recreating a nested generator on every call. Give processPayment the concrete job of producing an HTTP response, remove repeated explanations, and point directly to error handling so the tutorial keeps attention on typed failures and the happy path.
Returning Response from processPayment made the later examples misleading because they still treated its success as an Authorization. Carry the HTTP response contract through typed handlers and defect examples, and perform capture before response construction, so the tutorial teaches expected errors, defects, and boundaries through one stable payment flow.
The preceding section already establishes that these errors were modeled. Removing the repeated qualifier keeps the heading focused on the reader's next task: handling them.
The old headings mixed abstract labels with references to the tutorial example. Naming the reusable Effect concepts instead helps readers scan the page for the operation they need without tying those lessons to the payment scenario.
Show error unions at the points where they are introduced and narrowed so beginners can connect catchTag and catchTags to the resulting Effect type. Remove the repeated all-errors-handled example and use consistent names and comments because the extra scaffolding obscured the never takeaway.
Call out that TypeScript cannot prove the catch branches are exhaustive because thrown errors are unknown. This makes the fallback's purpose explicit and reinforces the cost of errors that are absent from the function signature.
Separate invariant violations, typed-error conversion, and boundary recovery so each Effect API appears only after the reader understands the scenario that requires it. Remove repeated payment scaffolding and clarify the Cause and never distinction to prevent defects from being confused with expected errors.
Define the boundary where the reconciliation job calls processPayment so orDie is tied to a concrete caller decision. Clarify that typed errors offer type-safe recovery without forcing every caller to handle them, preventing error modeling from sounding like mandatory boilerplate.
Integrate capturePayment into processPayment so readers can see how defects coexist with the expected error union instead of remaining an isolated fixture. Verify the continuation with Twoslash and sharpen the boundary heading because defect recovery is appropriate only when continuing is safe.
Use the real payment flow so catchDefect shows how an HTTP handler can contain a known defect while preserving the expected error union. Explain that defects are unknown by design and rethrow unrecognized values because boundary recovery must not resume or hide an unsafe computation.
Organize the recap by situation, action, and effect on the type so readers can apply the error model instead of memorizing an API list. This keeps expected errors, boundary choices, and defects distinct at the point where the tutorial consolidates them.
Cover the main concepts and APIs introduced by the tutorial so readers can choose the right next guide without guessing. Present the links as the same responsive cards used elsewhere in the docs, which makes the options easier to scan and avoids the runtime incompatibility of Starlight's CardGrid in this MDX setup.
@f15u
f15u force-pushed the tutorial/error-modeling branch from 24b3672 to bade585 Compare September 17, 2026 00:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants