chore: adopt @unthrown/oxlint recommended rules - #613
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Pre-3.0 stabilization sweep that hardens runtime behavior (wire-format correctness, shutdown/drain semantics, connection pooling safety, telemetry/interceptor safety) while finalizing several 3.0 API shapes and syncing tests/docs/tooling (including adopting @unthrown/oxlint rules).
Changes:
- Hardened core runtime behavior: byte-for-byte Buffer publishing (compression/retry safety), per-consumer prefetch, idempotent connection leases, safe telemetry/interceptor execution, and worker drain-on-close.
- Finalized/broke APIs for 3.0:
declare*naming, RPC error declarations as{ data, message? }, standalone topology indefineContract, curated workerConsumerOptions, and updated inference types. - Expanded/updated invariant coverage and documentation: new e2e/spec tests (compression, drain, DLQ routing, pooling), docs/README sync, and oxlint plugin adoption.
Reviewed changes
Copilot reviewed 83 out of 84 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/src/rpc.spec.ts | Updates RPC tests for new RPC error map shape and adds DLQ routing invariants. |
| tests/src/rabbitmq-config.spec.ts | Imports testing global-setup for Vitest context augmentation used by inject(). |
| tests/src/middleware.spec.ts | Migrates to declareMiddleware and adds coverage for middleware array composition. |
| tests/src/compression.spec.ts | Adds end-to-end compression wire-format regression tests (gzip/deflate + plain). |
| tests/src/client-worker.spec.ts | Updates fixtures to .get() and migrates handlers helper to declareHandlers. |
| tests/package.json | Adds typecheck script for the tests workspace package. |
| README.md | Syncs public quickstart docs with .get()/.getOrThrow() guidance and AsyncAPI 3.1 wording. |
| pnpm-workspace.yaml | Adds @unthrown/oxlint to catalogs and excludes it from minimum release age gating. |
| pnpm-lock.yaml | Locks @unthrown/oxlint@5.0.0 and its transitive deps. |
| packages/worker/src/worker.ts | Adds drain-on-close with timeout, curated ConsumerOptions, middleware array support, fail-fast handler validation, safe nack, and RPC error default message behavior. |
| packages/worker/src/worker-cleanup.spec.ts | Adds coverage for fail-fast behavior when handler entries are present but non-callable. |
| packages/worker/src/types.ts | Aligns RPC response/error inference to the new { data } error shape and response input typing. |
| packages/worker/src/retry.ts | Fixes classic immediate-requeue retry republish to default exchange + preserves raw bytes on retry. |
| packages/worker/src/middleware.ts | Renames defineMiddleware → declareMiddleware and updates docs/examples. |
| packages/worker/src/middleware.spec.ts | Updates middleware unit tests to declareMiddleware. |
| packages/worker/src/invariants.spec.ts | Adds invariant test for classic immediate-requeue retry republish routing. |
| packages/worker/src/index.ts | Re-exports core types/guards + renames exports to declare* and exports DEFAULT_DRAIN_TIMEOUT_MS. |
| packages/worker/src/handlers.ts | Adds invalid-handler detection and renames handler helpers to declareHandler(s). |
| packages/worker/src/handlers.test-d.ts | Expands type-level coverage for RPC error/response inference, headers, options, and middleware context. |
| packages/worker/src/handlers.spec.ts | Updates runtime handler helper tests for declare* and adds invalid-entry checks. |
| packages/worker/src/tests/worker.spec.ts | Updates worker integration tests to declareHandler(s). |
| packages/worker/src/tests/worker-retry.spec.ts | Adds invariant test ensuring validation failures bypass retry pipeline (DLQ on first delivery). |
| packages/worker/src/tests/worker-close-drain.spec.ts | Adds integration guard for draining in-flight handlers during close(). |
| packages/worker/README.md | Syncs worker README to declareHandler(s) naming. |
| packages/worker/package.json | Marks package as sideEffects: false. |
| packages/testing/src/extension.ts | Exports named fixture/types and renames wait options { nbEvents, timeout } → { count, timeoutMs }. |
| packages/testing/package.json | Marks sideEffects: false and exports ./package.json. |
| packages/core/src/telemetry.ts | Makes telemetry helpers swallow provider/span throws to keep data path non-throwing. |
| packages/core/src/telemetry.spec.ts | Adds coverage for throwing telemetry providers/spans (must not throw). |
| packages/core/src/index.ts | Cleans up exports and re-exports new guards/types; removes deprecated testing aliases. |
| packages/core/src/errors.ts | Adds isTechnicalError/isMessageValidationError type guards. |
| packages/core/src/connection-manager.ts | Refactors pooling to explicit idempotent leases and fixes acquire/release/close races. |
| packages/core/src/connection-manager.spec.ts | Adds pooling invariant tests (double release, acquire-vs-close race, rejecting close). |
| packages/core/src/amqp-client.ts | Disables ACM json mode, adds explicit content encoding, uses connection leases, memoizes close(), and validates prefetch/connect timeout inputs. |
| packages/core/README.md | Syncs examples to .get() extraction for create(). |
| packages/core/package.json | Marks package as sideEffects: false. |
| packages/contract/src/types.ts | Adds InferSchemaInput/Output, updates RPC error typing to { data, message? }, and supports standalone topology keys. |
| packages/contract/src/index.ts | Re-exports new contract types (schema inference, RPC error definition, retry/types hygiene). |
| packages/contract/src/builder/validate.spec.ts | Updates RPC error validation tests to new { data } shape. |
| packages/contract/src/builder/standalone-topology.spec.ts | Adds tests for standalone exchanges/queues/bindings and infrastructure extraction/dedupe. |
| packages/contract/src/builder/rpc.ts | Updates RPC docs and runtime validation for error entry shape { data, message? }. |
| packages/contract/src/builder/rpc.spec.ts | Updates RPC unit tests for new error definition shape and unknown-key rejection. |
| packages/contract/src/builder/contract.ts | Implements standalone topology extraction + unifies queue infrastructure extraction logic. |
| packages/contract/src/builder/command.ts | Preserves literal routing-key types in defineCommandPublisher signatures. |
| packages/contract/src/builder.test-d.ts | Adds/updates type-level tests for RPC errors and standalone topology typing. |
| packages/contract/package.json | Marks package as sideEffects: false. |
| packages/client/src/types.ts | Centralizes schema inference imports and adds ClientInferCallError union type for call() errors. |
| packages/client/src/interceptors.ts | Guards synchronous throws in interceptors/terminal by adopting them into the Defect channel. |
| packages/client/src/interceptors.spec.ts | Adds tests ensuring sync-throwing interceptors/terminal become Defects (never raw throws). |
| packages/client/src/index.ts | Re-exports core guards/types and exports named error unions/types (CallError, PublishError, ClientInferCallError). |
| packages/client/src/client.ts | Routes constructor sync throws to defect channel; uses new error schema shape { data, message? }; clarifies publish content handling. |
| packages/client/src/client.test-d.ts | Adds type-level tests for RPC call request/response/errors and required options. |
| packages/client/package.json | Marks package as sideEffects: false. |
| packages/asyncapi/src/index.ts | Updates docs to AsyncAPI 3.1 and makes failOnMissingConverter default to true. |
| packages/asyncapi/src/index.spec.ts | Adds/updates tests for the new “fail by default” missing-converter behavior. |
| packages/asyncapi/README.md | Updates README to AsyncAPI 3.1 wording. |
| packages/asyncapi/package.json | Marks package as sideEffects: false. |
| package.json | Adds @unthrown/oxlint dev dependency via catalog. |
| examples/basic-order-processing-worker/src/index.ts | Migrates to declareHandlers and uses qualifyRetryable for fromPromise qualification. |
| examples/basic-order-processing-worker/src/index.spec.ts | Migrates tests to declareHandlers and .get() patterns. |
| examples/basic-order-processing-worker/README.md | Syncs example docs to .get() and declareHandler(s) naming. |
| examples/basic-order-processing-contract/README.md | Syncs contract example to .get() extraction. |
| examples/basic-order-processing-client/src/index.ts | Demonstrates publish interceptors and updates publish flow to .getOrThrow() at call sites. |
| docs/tutorial/adding-request-reply.md | Syncs tutorial to new RPC error shape and includes MessageValidationError in call error handling. |
| docs/reference/topology-options.md | Documents standalone topology, curated worker options, drain timeout, and schema inference helpers. |
| docs/reference/schema-libraries.md | Updates missing-converter behavior to “fail by default” and explains opt-out. |
| docs/reference/error-model.md | Syncs error model docs with new exports/guards and RPC error shape. |
| docs/index.md | Updates marketing copy to AsyncAPI 3.1. |
| docs/how-to/use-request-reply.md | Syncs example to { data } RPC errors. |
| docs/how-to/troubleshoot.md | Updates troubleshooting entries for declareHandler naming and connectTimeout behavior. |
| docs/how-to/test-with-rabbitmq.md | Syncs testing docs to declareHandlers and { count, timeoutMs } wait options. |
| docs/how-to/route-dead-letters.md | Adds standalone topology DLQ example documentation. |
| docs/how-to/generate-asyncapi.md | Updates generator docs for AsyncAPI 3.1 and fail-by-default converter behavior. |
| docs/how-to/define-a-contract.md | Documents standalone topology declarations in defineContract. |
| docs/how-to/consume-messages.md | Updates handler helper naming and documents drain timeout behavior on close. |
| docs/how-to/add-middleware.md | Syncs middleware docs to declareMiddleware and documents array form tradeoffs. |
| docs/examples/command-pattern.md | Updates example naming to declareHandler. |
| AGENTS.md | Updates invariant mapping and documents new invariants/guards added in this sweep. |
| .oxlintrc.json | Registers @unthrown/oxlint plugin and enables recommended unthrown rules. |
| .changeset/pre-3-0-robustness-fixes.md | Changeset for runtime hardening and robustness fixes. |
| .changeset/pre-3-0-api-review.md | Changeset documenting the 3.0 breaking API review sweep. |
| .agents/rules/testing.md | Updates fixture wait options docs to { count, timeoutMs }. |
| .agents/rules/recipes.md | Updates recipes to declareHandler(s) and new RPC error entry shape. |
| .agents/rules/handlers.md | Updates handler guidance for declareHandler(s) naming and related docs. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Register the unthrown oxlint plugin in .oxlintrc.json and enable the recommended rule set as errors: no-ambiguous-error-type, no-catch-all-pattern, no-unhandled-result, prefer-async-result (the two opt-ins, no-throw and prefer-ensure, stay off). The package rides the catalog and is excluded from the supply-chain maturity gate as a first-party btravstack library. Violations fixed: - prefer-async-result (3): the internal never-rejecting async work thunks in TypedAmqpClient.create, TypedAmqpWorker.create, and AmqpClient.close were annotated Promise<Result<T, never>>. Dropped the redundant return annotations — inference yields the same type, and the thunks are immediately adopted by fromSafePromise, so no raw Promise<Result> crosses an API boundary. Removed the now-unused Result type import in amqp-client.ts. - no-ambiguous-error-type, no-catch-all-pattern, no-unhandled-result: zero findings. No disables were needed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
btravers
force-pushed
the
fix/pre-3.0-full-review
branch
from
July 30, 2026 01:09
21dec2f to
06caa2f
Compare
Turn on the two opt-in rules (unthrown/no-throw, unthrown/prefer-ensure) on top of the recommended set. prefer-ensure reported zero violations; the 40 no-throw sites are all deliberate — fail-fast declaration-time config validation in the builders/handlers, defect-channel routing inside fromSafeThrowable/combinator thunks, and vitest fixtures — and now carry targeted oxlint-disable comments naming their reason. Test files get an oxlintrc override turning no-throw off (the other rules stay on). Also reword the import comment in tests/src/rabbitmq-config.spec.ts: the global-setup import is a runtime side-effect import (it executes top-level module code and loads testcontainers), not a type-only one (review feedback on PR #613). Add the changeset the ci/Changeset check was failing over: the branch touches package sources (annotation cleanup + lint comments) with no changeset since main — a patch entry now covers the six publishable packages (fixed group), no runtime behavior change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 20 out of 21 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Comments suppressed due to low confidence (1)
.oxlintrc.json:11
- The PR description says the opt-in rules
unthrown/no-throwandunthrown/prefer-ensure“stay off”, but this config enables both aserror. Please reconcile the PR intent: either disable these two rules here, or update the PR description/changeset messaging to reflect that they’re being enabled.
"unthrown/no-throw": "error",
"unthrown/no-unhandled-result": "error",
"unthrown/prefer-async-result": "error",
"unthrown/prefer-ensure": "error"
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
Registers the
@unthrown/oxlintplugin with the four recommended rules (no-ambiguous-error-type,no-catch-all-pattern,no-unhandled-result,prefer-async-result; the opt-insno-throw/prefer-ensurestay off).@unthrown/oxlintjoins the first-partyminimumReleaseAgeExcludelist (published inside the 7-day supply-chain gate; same treatment asunthrownand@unthrown/vitest).3 violations found, all
prefer-async-resulton redundantPromise<Result<T, never>>work-thunk annotations (TypedAmqpWorker.create,TypedAmqpClient.create,AmqpClient.close) — fixed by dropping the annotations; inference yields identical types. Zero disables needed: every publicEchannel already names concrete@amqp-contract/*tagged errors and every matcher enumerates its arms.Mirror adoption in temporal-contract: btravstack/temporal-contract#356.
Verification
pnpm lintclean;pnpm turbo run typecheck test22/22 tasks;pnpm test:integration13/13 tasks against RabbitMQ testcontainers.🤖 Generated with Claude Code