feat!: adopt unthrown v5 (beta) - #596
Merged
Merged
Conversation
Bump unthrown/@unthrown/vitest to 5.0.0-beta.2 (catalog + peer ranges), enter changesets beta pre-mode, and migrate to the v5 error-channel API: error combinators (mapErr/flatMapErr/recoverErr/tapErr/flatTapErr) and match's err handler now take a ts-pattern matcher callback returning an exhaustive builder; matchTags is folded into match(...).with(tag(...)). BREAKING CHANGE: unthrown peer moved ^4 -> ^5.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR upgrades the monorepo to unthrown v5.0.0-beta.2, migrating error-channel combinators and Result.match’s err branch to the new ts-pattern matcher-callback API, and sets the repo up for a beta pre-release via Changesets.
Changes:
- Bumped
unthrownand@unthrown/vitestto5.0.0-beta.2(catalog + lockfile) and updated package peer ranges to^5.0.0-beta.2. - Migrated worker/client code to v5’s matcher-callback shape for
mapErr/flatMapErr/tapErrand updated docs/examples accordingly. - Entered Changesets pre mode (
tag: beta) and added a major changeset for the fixed group.
Reviewed changes
Copilot reviewed 19 out of 20 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-workspace.yaml | Bumps catalog entries for unthrown + @unthrown/vitest to v5 beta.2. |
| pnpm-lock.yaml | Updates resolved versions/snapshots for the v5 beta.2 upgrade. |
| packages/worker/src/worker.ts | Migrates worker error combinators to v5 matcher-callback API; adds one explicit fromPromise type arg workaround. |
| packages/worker/src/retry.ts | Updates retry publish error recovery to v5 matcher-callback API. |
| packages/worker/src/errors.ts | Updates docs/comments to describe v5 matcher-based tagged-error dispatch. |
| packages/worker/package.json | Bumps unthrown peer dependency range to ^5.0.0-beta.2. |
| packages/core/src/parsing.ts | Adapts safeJsonParse to v5’s NotThenable-intersected qualify typing. |
| packages/core/src/errors.ts | Updates docs/comments to describe v5 matcher-based tagged-error dispatch. |
| packages/core/package.json | Bumps unthrown peer dependency range to ^5.0.0-beta.2. |
| packages/client/src/interceptors.ts | Updates interceptor docs to reflect v5 matcher-callback usage. |
| packages/client/src/interceptors.spec.ts | Updates tests to v5 matcher-callback API. |
| packages/client/src/client.ts | Migrates client error combinators / examples to v5 matcher-callback API. |
| packages/client/package.json | Bumps unthrown peer dependency range to ^5.0.0-beta.2. |
| examples/basic-order-processing-worker/src/index.ts | Updates example worker error handling to v5 matcher-callback API. |
| examples/basic-order-processing-client/src/index.ts | Updates example client error handling to v5 matcher-callback API. |
| examples/basic-order-processing-client/package.json | Moves unthrown to runtime deps to support new runtime import usage. |
| docs/guide/upgrading.md | Updates upgrade guide wording/snippets for v5 matcher-based dispatch. |
| .changeset/pre.json | Enters Changesets pre-mode for beta publishing. |
| .changeset/adopt-unthrown-v5-beta.md | Adds major changeset describing the v5 beta migration and peer bump. |
| .agents/rules/handlers.md | Updates agent guidance to document v5 matcher-callback API and match semantics. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
…ble lines The fresh GHSA-mh99-v99m-4gvg (DoS via unbounded expansion length) reddened the audit gate. Its only patched release is 5.0.8 on the 5.x line — applied via the override (with a temporary minimumReleaseAgeExclude entry; 5.0.8 is younger than the 7-day cutoff, published 2026-07-23). The 1.x/2.x lines under @asyncapi/parser>spectral and testcontainers>archiver have NO patched release and a cross-major force is unsafe, so the advisory is ignored via auditConfig.ignoreGhsas with the accepted-risk rationale (expansion input is library-internal glob patterns, never user input) and removal criteria.
Address review: the qualifier's `as E & NotThenable<E>` cast defeated
unthrown v5's non-thenable safeguard (a thenable error returned by errorFn
would be silently accepted). Move the constraint onto safeJsonParse's own
`errorFn` parameter — it flows to `fromThrowable`'s qualify with no cast, and
a thenable error type is now rejected at the call site. For every real domain
error (extends Error) NotThenable<E> is unknown, so callers see plain E.
Also add the missing `import { ErrAsync, P }` to the CallInterceptor JSDoc
example so it is copy/paste-runnable.
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.
Summary
Adopts unthrown
5.0.0-beta.3across the monorepo. beta.2 fixed the async-flatMapinference regression; beta.3 fixes the two remaining v5 inference regressions (concreteErr/Okwidening into a generic error union, andfromPromiseTinference with an inlinePromise.resolve().then(...)argument — the async-qualify ban moved offqualify's return type onto a phantom rest-tuple guard). The consumer code now compiles against the v5 error-channel API with no inference workarounds — except onefromThrowable-related re-assert, noted below.Changes
unthrownand@unthrown/vitestat5.0.0-beta.3; peer ranges^5.0.0-beta.3inpackages/{core,client,worker}..changeset/pre.json, tagbeta).mapErr/flatMapErr/recoverErr/tapErr/flatTapErr) andmatch'serrhandler now take a ts-pattern matcher callback that returns an exhaustive builder (the combinator owns.exhaustive()). Rough counts acrosspackages/*+examples/*:P._catch-all branchesmatchTagscall sites removed — folded intomatch(...).with(tag(...), …)tag(...)pattern usagesqualifyboundaries unchanged in shape (already(cause, defect) => …).docs/guide/upgrading.md,.agents/rules/handlers.md).Inference workarounds
packages/worker/src/worker.ts— thecreateContextseed'sfromPromise<Record<string, unknown>, HandlerError>(…)explicit type args, added under beta.2 becauseTcollapsed tounknown. Now plainfromPromise(…)and inference holds.packages/core/src/parsing.ts—safeJsonParse'sE & NotThenable<E>re-assert at itsfromThrowableboundary. beta.3 did not movefromThrowable'sNotThenableconstraint offqualify's return type, and TypeScript cannot prove it for an unconstrained genericE; the assert collapses to plainEfor every real (non-thenable) error type.Gate (all green locally)
pnpm format --checkpnpm lintpnpm typecheckpnpm knippnpm test(coverage thresholds intact)pnpm build(incl.build:docs, 0 errors)Integration tests (Docker/RabbitMQ) were not run in this environment.
Release
Major changeset added (unthrown peer
^4→^5, now^5.0.0-beta.3). In beta pre-mode this publishes the fixed group at3.0.0-beta.0(from2.4.0) on merge.changeset versionwas not run.