# Error Handling Resources

⭐ marks the core set. Sources added in session 3 for the application-level refocus are grouped
under **Application level**; the theory sources that ground the vocabulary are kept below them.

## Application level — the boundary: where to throw, where to catch

- ⭐ [Essay: "Parse, don't validate" — Alexis King (2019)](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/)
  A parser is *"a function that consumes less-structured input and produces more-structured output."*
  Validation checks and throws the result away; parsing checks and keeps it in the type.
  Use for: why input handling belongs at the boundary, the rules *"push the burden of proof upward
  as far as possible, but no further"* and *"use a data structure that makes illegal states
  unrepresentable."* Also the source for **shotgun parsing** (credited to *The Seven Turrets of
  Babel*, 2016): validation *"mixed with and spread across processing code"* — the reason half-processed
  input leaves unpredictable state.
- ⭐ [Essay: "The Error Model" — Joe Duffy (2016)](https://joeduffyblog.com/2016/02/07/the-error-model/)
  The bug vs. recoverable-error split, and abandonment. Use for: the criterion that decides throw-vs-return
  before any language-specific argument starts.
- [Essay: "The Second Great Error Model Convergence" — Alex Kladov / matklad (2025)](https://matklad.github.io/2025/12/29/second-error-model-convergence.html)
  Use for: the argument that first-class error values + call-site-marked propagation + a separate panic
  channel is where the field landed — the strongest available case for the `Result`-style camp in TypeScript.
- ⭐ [Interview: "The Trouble with Checked Exceptions" — Anders Hejlsberg, Artima 2003](https://www.artima.com/articles/the-trouble-with-checked-exceptions)
  Use for: the other camp, honestly. Versioning (*"It is a breaking change for me to add `D` to the throws
  clause"*) and scalability (*"you have this exponential hierarchy below you… You end up having to declare
  40 exceptions"*), plus the observed workarounds — `throws Exception` everywhere, empty catch blocks.

## Application level — the wire: what an error looks like leaving the backend

- ⭐ [RFC 9457 — Problem Details for HTTP APIs (2023, obsoletes RFC 7807)](https://www.rfc-editor.org/rfc/rfc9457.html)
  Media type `application/problem+json`. Members: `type` (URI identifying the problem *type*),
  `title` (stable human summary of the type), `status`, `detail` (*"a human-readable explanation
  specific to this occurrence"* — must help the client **correct** the problem, not debug it),
  `instance` (URI or opaque id for the occurrence). Extensions carry machine-readable specifics;
  consumers *"MUST ignore any such extensions that they don't recognize."*
  Use for: the default envelope shape, and the argument that clients must not parse `detail`.
- ⭐ [Google AIP-193 — Errors](https://google.aip.dev/193)
  `google.rpc.Status` = code + message + details, with a mandatory `ErrorInfo` carrying
  `reason` (SCREAMING_SNAKE, stable), `domain` (service name), `metadata`. The message is explicitly
  **developer-facing**; errors *"must not assume that the user will know anything about its underlying
  implementation"*, and *"any request-specific information which contributes to the message must be
  represented within `metadata`"* so it can be re-rendered or localised.
  Use for: the two-audience split, and why the machine-readable reason must be separate from the prose.
- ⭐ [Stripe API — error handling](https://docs.stripe.com/error-handling) and
  [idempotent requests](https://docs.stripe.com/api/idempotent_requests)
  A production error taxonomy worth copying: card / invalid-request / connection / API / auth /
  idempotency / permission / rate-limit / signature, each with a prescribed *response*. Fields:
  `type`, `code`, `param`, `doc_url`, `request_log_url`, request ID. Crucially, for connection and API
  errors: *"Treat the result of the API call as indeterminate. That is, don't assume that it succeeded
  or that it failed."* Idempotency: the first result (status **and** body, success or failure) is saved
  against the key, replays return it, reusing a key with different parameters is an error, keys prune
  after 24h, POST only.
  Use for: naming an **indeterminate outcome**, and the canonical idempotency-key contract.
- [Book: _Release It!_ (2nd ed.) — Michael Nygard](https://pragprog.com/titles/mnee2/release-it-second-edition/)
  Circuit breaker, bulkhead, timeout, fail fast, steady state. Use for: named vocabulary for containment
  between services.
- [Book: _Site Reliability Engineering_ — Google, ch. 22 "Addressing Cascading Failures"](https://sre.google/sre-book/addressing-cascading-failures/)
  Use for: retry amplification, retry budgets, backoff + jitter, load shedding — how error *handling*
  becomes the outage.

## Application level — the user: presenting failure

- ⭐ [Article: "Error Message Guidelines" — Nielsen Norman Group](https://www.nngroup.com/articles/error-message-guidelines/)
  The reference for user-facing copy and placement. *"Display the error message close to the error's
  source."* *"Avoid technical jargon and use language familiar to your users."* *"Don't use phrasing that
  blames users… such as invalid, illegal, or incorrect."* Merely stating the problem is insufficient —
  *"offer some potential remedies."* Preserve the user's input; never rely on colour alone; match the
  surface (inline / toast / modal) to severity.
  Use for: every decision about what the end user sees.

## Application level — containment: what happens on the unexpected

- ⭐ [React docs — error boundaries (`Component`)](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary)
  Catches errors thrown during **rendering** of children. Explicitly does **not** catch: event handlers,
  server-side rendering, asynchronous code (`setTimeout`, `requestAnimationFrame`), or errors thrown in
  the boundary itself. `static getDerivedStateFromError` must be pure and produces the fallback state;
  `componentDidCatch` is where the side effect (reporting) goes. Granularity guidance: a boundary around
  a conversation list and around each message makes sense — one around every avatar does not.
  Use for: the frontend backstop, and precisely what it leaves uncovered.
- ⭐ [MDN — `unhandledrejection` event](https://developer.mozilla.org/en-US/docs/Web/API/Window/unhandledrejection_event)
  Fires for rejected promises with no handler; the `error` event covers synchronous throws and resource
  failures. Cancelable via `preventDefault()`; `rejectionhandled` fires if a handler is attached late.
  Cross-origin rejections are suppressed. Explicitly a *last-resort* handler, not a strategy.
  Use for: the two global browser backstops and the gap between them.
- ⭐ [Paper: "Crash-Only Software" — Candea & Fox, HotOS IX, 2003](https://dslab.epfl.ch/pubs/crashonly.pdf)
  Collapsing shutdown and crash into one path, so recovery is the only code path and it is exercised
  constantly. Use for: the argument for crashing a process rather than limping on after an unexpected error.
- ⭐ [Thesis: "Making reliable distributed systems in the presence of software errors" — Joe Armstrong, 2003](https://erlang.org/download/armstrong_thesis_2003.pdf)
  Supervision trees, let-it-crash, error kernels, isolation as the precondition for recovery.
  Use for: why "restart from a known state" beats "recover in place", and what isolation it requires.
- [Article: "Fail Fast" — Jim Shore, IEEE Software 21(5), 2004](https://martinfowler.com/ieeeSoftware/failFast.pdf)
  Use for: assertions as a debugging strategy; the fail-fast argument stated plainly.

## Theory — the vocabulary underneath

- ⭐ [Essay: "An epic treatise on error models for systems programming languages" — Varun Gandhi (2025)](https://typesanitizer.com/blog/errors.html)
  The axes: representation, propagation, handling, plus metadata and granularity.
  Use for: comparing TypeScript, Rust, Go and Python on the same page rather than as tribal preferences.
- ⭐ [Blog: "Don't just check errors, handle them gracefully" — Dave Cheney (2016)](https://dave.cheney.net/2016/04/27/dont-just-check-errors-handle-them-gracefully)
  Sentinel / error type / opaque, and *"assert errors for behaviour, not type."*
  Use for: how much of a failure to make public, in any language.
- ⭐ [Exception safety guarantees — David Abrahams (summary: Wikipedia)](https://en.wikipedia.org/wiki/Exception_safety)
  Nothrow / strong / basic / none. The only widely agreed formal vocabulary for "what state am I in
  after an early exit?" Use for: reasoning about half-completed operations, in any language.
- ⭐ [Paper: "Applying Design by Contract" — Bertrand Meyer, IEEE Computer 1992](https://se.inf.ethz.ch/~meyer/publications/computer/contract.pdf)
  Preconditions / postconditions / invariants and the blame rule.
  Use for: the principled answer to "is this my caller's problem or mine?"
- [PEP 654 — Exception Groups and `except*`](https://peps.python.org/pep-0654/)
  Use for: error aggregation as a language feature — many unrelated failures propagating at once.
  The JavaScript counterpart is `AggregateError` / `Promise.allSettled`.
- [Paper: "Exception handling: issues and a proposed notation" — Goodenough, CACM 1975](https://dl.acm.org/doi/10.1145/361227.361230)
  Where the vocabulary came from; termination vs. resumption semantics.

## Gaps

- **No high-trust source found for the throw-vs-`Result` question in TypeScript specifically.** The
  arguments have to be assembled from Hejlsberg (against declared exceptions), Kladov (for values),
  and library docs (`neverthrow`, `effect`, `fp-ts`), none of which is neutral. Lessons treating this
  must present it as contested and flag the synthesis.
- **No canonical source on mapping machine-readable error codes to localised user copy.** AIP-193's
  `LocalizedMessage` + `metadata` is the closest thing to a specification; everything else is vendor
  practice. Flag as synthesis.
- **Global error collectors** (Sentry-style aggregation, error grouping/fingerprinting, sampling) as a
  design category rather than a vendor feature — still no neutral source. Needs synthesis from vendor
  docs plus the SRE material.
- **Empirical evidence** on error-handling defect rates is scattered; no single review found.
