refactor!: *Cases error-matcher rename + v5-beta migration fixes (#142–#146) - #147
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR completes the v5-beta API migration around exhaustive error matching by finalizing the *Cases renames (including match({ …, errCases })), switching ts-pattern to a peer dependency to avoid dual-copy type collisions, and adding/aligning documentation and migration guidance for 4.x → 5.0 adopters.
Changes:
- Make
ts-patternapeerDependency(^5) forunthrowncore, and update install/docs accordingly. - Finalize the
*Casesrename across code, tests, and docs (mapErrCases,recoverErrCases,match({ errCases }), etc.), including type-level guards for previously silent breaks. - Improve migration experience: clearer
getOrThrow()never-channel diagnostic and new 4.x → 5.0 upgrade docs (MIGRATION.md+ VitePress how-to).
Reviewed changes
Copilot reviewed 55 out of 56 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| README.md | Update install instructions and match example to errCases + peer dep note. |
| pnpm-lock.yaml | Lockfile updates reflecting ts-pattern dependency move. |
| packages/prisma/README.md | Update match handler key to errCases. |
| packages/orpc/src/types.test-d.ts | Update guidance text to mapErrCases. |
| packages/orpc/src/server.ts | Update docs/comments and references to mapErrCases / errCases. |
| packages/orpc/src/index.spec.ts | Update test usage to errCases. |
| packages/orpc/src/extensions/result.ts | Update inline example to mapErrCases. |
| packages/orpc/src/client.ts | Update docs to errCases. |
| packages/orpc/README.md | Update README examples and wording to mapErrCases / errCases. |
| packages/neverthrow/src/index.ts | Update comment referencing errCases matcher. |
| packages/effect/src/index.ts | Update comment referencing errCases matcher. |
| packages/effect/README.md | Update example to errCases. |
| packages/core/src/types.ts | Rename method surface types/docs (*Cases, errCases) + improve getOrThrow diagnostic. |
| packages/core/src/types.test-d.ts | Update type tests for new names; add guard for old match({ err }) shape; document generic-E limitation. |
| packages/core/src/tagged.ts | Update docs/examples to mapErrCases. |
| packages/core/src/tagged.spec.ts | Update tests for errCases. |
| packages/core/src/result.spec.ts | Update tests for *Cases combinators and match({ errCases }). |
| packages/core/src/invariants.spec.ts | Update invariant tests for *Cases combinators. |
| packages/core/src/index.ts | Update ts-pattern re-export comment to new naming. |
| packages/core/src/core.ts | Rename internal implementations to *Cases and match handler to errCases. |
| packages/core/src/async-result.spec.ts | Update async surface tests for *Cases combinators and errCases. |
| packages/core/README.md | Update install instructions, examples, and link to v5 upgrade guide. |
| packages/core/package.json | Move ts-pattern from dependency → peerDependency; keep as devDependency for workspace tooling. |
| packages/boxed/src/index.ts | Update comment referencing errCases matcher. |
| MIGRATION.md | Add top-level 4.x → 5.0 migration summary and link to docs guide. |
| docs/tutorial/getting-started.md | Update install commands and examples to include ts-pattern and errCases. |
| docs/tutorial/crossing-an-async-boundary.md | Update example to errCases. |
| docs/reference/result-surface.md | Update combinator naming in reference surface section. |
| docs/reference/glossary.md | Update glossary entry to mapErrCases. |
| docs/reference/combinators.md | Update reference tables and narrative for *Cases naming and recoverErrCases. |
| docs/index.md | Update homepage example to errCases. |
| docs/how-to/validate-with-standard-schema.md | Update example to errCases. |
| docs/how-to/use-with-prisma.md | Update narrative/examples to errCases. |
| docs/how-to/use-with-orpc.md | Update examples and narrative to mapErrCases / errCases. |
| docs/how-to/upgrade-to-v5.md | Add new 4.x → 5.0 checklist/migration guide. |
| docs/how-to/sequence-dependent-steps.md | Update examples to errCases. |
| docs/how-to/qualify-a-boundary.md | Update example to errCases. |
| docs/how-to/model-errors.md | Update narrative/examples to errCases and mapErrCases naming. |
| docs/how-to/migrate-from-try-catch.md | Update guidance/examples to mapErrCases / tapErrCases / errCases. |
| docs/how-to/migrate-from-neverthrow.md | Update mapping table and examples to mapErrCases / flatMapErrCases / errCases. |
| docs/how-to/interoperate-with-libraries.md | Update example to errCases. |
| docs/how-to/handle-results-at-the-edge.md | Update examples and references to errCases and recoverErrCases / flatMapErrCases. |
| docs/explanation/why-unthrown.md | Update example to errCases. |
| docs/explanation/the-defect-channel.md | Update method names and section headings to *Cases. |
| docs/explanation/qualification.md | Update narrative to mapErrCases. |
| docs/explanation/exhaustive-error-matching.md | Update explanation to reflect *Cases naming and add generic-helper limitation guidance. |
| docs/explanation/design-decisions.md | Update design decision rationale to *Cases suffix. |
| docs/explanation/async-model.md | Update naming in async model explanation (flatMapErrCases). |
| docs/.vitepress/config.ts | Add sidebar entry for the v5 upgrade guide. |
| CLAUDE.md | Update internal spec text to *Cases/errCases and peer dep rationale. |
| .changeset/ts-pattern-peer-dependency.md | Changeset: ts-pattern becomes peerDependency (major). |
| .changeset/synchronous-qualify-and-taperr.md | Changeset text updated to tapErrCases naming. |
| .changeset/runtime-hardening.md | Changeset text updated to flatMapErrCases / flatTapErrCases naming. |
| .changeset/rename-err-combinators-cases.md | Changeset: document *Cases rename and err → errCases. |
| .changeset/getorthrow-never-gate-message.md | Changeset: document improved getOrThrow() gate diagnostic. |
| .changeset/exhaustive-error-matcher.md | Changeset text updated to mapErrCases and errCases naming. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Comments suppressed due to low confidence (1)
docs/reference/combinators.md:73
- This link anchor still uses
#recovererr-…, but the target section header is now "recoverErrCases…", so the generated slug will change and this link will likely break. Update the anchor to match the new heading slug.
[The Defect Channel](../explanation/the-defect-channel#recovererr-clears-the-error-channel-not-the-runtime).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
btravers
commented
Jul 27, 2026
unthrown re-exports ts-pattern's match/P/tag and its error matchers speak ts-pattern's builder type. Pinned as a nested dependency, a consumer already using ts-pattern got two copies whose declarations don't unify — feeding a P.union(...) from one into an unthrown matcher failed deep in a conditional type. Declaring it a peer (^5) guarantees a single, consumer-owned copy. Kept as a devDependency (catalog) for the workspace's own build/test. Updated CLAUDE.md, the READMEs, and the install docs to say you install ts-pattern yourself. Closes #143
When E = never there is nothing to throw, so getOrThrow() is gated off and get() is the tool. The gate previously surfaced as an opaque "'this' context ... is not assignable to method's 'this' of type 'never'". The never receiver now carries a message, so the compiler prints why and points at get(). Behaviour is unchanged. Closes #144
match's error handler now carries the same …Cases suffix as the error
combinators — it takes the exhaustive ts-pattern matcher, not a plain
(error) => … callback. This closes a silent runtime break: a leftover 4.x
err: (error) => … handler that threw still satisfied the matcher constraint
(a throwing handler returns never, which vacuously satisfies it), compiled,
and then threw the matcher object at runtime. The renamed key makes it an
excess-property compile error instead.
Renames match({ ok, err, defect }) → match({ ok, errCases, defect }) across
the API, tests, docs, interop packages, and the spec. Adds a type-d guard
that the old err key no longer compiles.
Closes #142
Inside a helper whose error type is still a type parameter, ts-pattern cannot prove any builder exhaustive — not even .with(P._, …) — so match/…Cases do not compile there. Generic boundary helpers (the interop to* bridges, oRPC's handlerResult) use the isOk/isErr/isDefect guards instead, which carry no exhaustiveness obligation. Documents this in the exhaustive-error-matching guide with the guard-based pattern, plus a type-d regression guard. Closes #145
@unthrown/pattern was absorbed into core and the 5.0 breaking surface (renamed error combinators, match's err → errCases, removed aliases, UnwrapError → GetError, the getOrThrow gate, ts-pattern as a peer) was only discoverable by diffing tarballs. Adds a how-to upgrade guide (in the sidebar) and a root MIGRATION.md with the headline list up front, linked from the core README. Closes #146
Review follow-up (#142 rename): the `match` row in the combinator matrix still showed `err()`, and the recoverErrCases tip linked a stale `#recovererr-…` anchor whose target header is now `recoverErrCases …`.
btravers
force-pushed
the
refactor/err-combinators-cases
branch
from
July 27, 2026 18:16
13c39d2 to
e1308f3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the five issues surfaced while migrating an 18-package client project onto
unthrown@5.0.0-beta. Rebased ontomain(beta.4) — the*Casescombinatorrename is already on
main, so this PR is now just the five fixes plus a reviewfollow-up. One commit per issue:
fix(core): make ts-pattern a peerDependency— Closes #143ts-patternmoves from a nested dependency to a peer (^5), so a consumeralready using ts-pattern shares one copy — two copies' declarations don't unify.
Kept as a
devDependencyfor the workspace. New changeset (major).fix(core): explain getOrThrow's never-channel gate— Closes #144The
E = nevergate now brands itsneverreceiver with a message, so thediagnostic says "getOrThrow is unnecessary here … use get() instead" instead
of an opaque
this-context error. Behaviour unchanged.refactor(core)!: rename match's err handler to errCases— Closes #142match({ ok, err, defect })→match({ ok, errCases, defect }). This is the one5.0 break the compiler almost missed: a leftover 4.x throwing
errhandlerreturned
never, vacuously satisfied the matcher constraint, compiled, and threwthe matcher object at runtime. The renamed key makes it an excess-property
compile error. Type-d guard added.
docs(core): document the generic-E matcher limitation— Closes #145ts-pattern can't prove any builder exhaustive (even
P._) behind an unresolvedgeneric
E, so generic boundary helpers must use theisOk/isErr/isDefectguards. Documented in the exhaustive-error-matching guide, plus a type-d guard.
(Confirmed
getOrThrow()is also concrete-E-only, so guards are the onegeneric-boundary tool — see the discussion on the
rawErrthread.)docs: add a 4.x to 5.0 migration guide— Closes #146New how-to upgrade guide (in the sidebar) + root
MIGRATION.mdwith the headlinebreaking surface, linked from the core README.
@unthrown/patternwas alreadyremoved from the repo.
docs: fix combinator matrix err() cell and defect-channel anchorReview follow-up: the
matchrow still showederr(), and therecoverErrCasestip linked a stale
#recovererr-…anchor.Still needs a manual step (npm credentials):
npm deprecate @unthrown/pattern "merged into unthrown@5 — import match/P/tag from 'unthrown'"Release
On merge, the changesets workflow publishes the next beta (5.0.0-beta.5 — a
pending major in pre mode). Gate green:
format --check,lint,typecheck,knip,test,build.