feat(api): shared abort-signal cancellation-scope helpers - #1651
easonLiangWorldedtech wants to merge 1 commit into
Conversation
…utils Extend src/api/providers/utils/abort-signal.ts with the abort-signal series helpers used by the gateway providers: - isRequestAborted(error, signal): wider abort detection - an aborted signal, a DOM AbortError, the OpenAI/Anthropic SDK APIUserAbortError (name check), or the exact SDK abort message "Request was aborted." - trusting name/message only on real Error instances so a plain object that merely looks like an abort propagates unchanged - createAbortError(providerName): fresh error satisfying the Task.ts abort contract (name "AbortError", message ending in "aborted") - rejectOnAbort(pending, signal, providerName): settle a signal-less async phase (model discovery) on the provider AbortError when the signal fires first; the abort listener detaches when pending settles - resolveModelWithAbort(fetchModel, signal, providerName): run model resolution inside a cancellation scope - entry fast-fail for a pre-aborted signal, the rejectOnAbort race while the lookup is pending, and normalization of abort-flavored lookup failures; any other resolution failure propagates unchanged Includes direct unit tests for the resolveModelWithAbort cancellation scope (pre-aborted fast-fail, no-signal pass-through, mid-resolution race, abort normalization, non-abort propagation), the isRequestAborted instanceof tightening tests, and the settle-guard test utility. Unit 1/3 of the Zoo-Code-Org#1295 split (content source: 62f596c5d). Part of the abort-signal series (round 1). Builds on Zoo-Code-Org#674, Zoo-Code-Org#901, Zoo-Code-Org#1008. Addresses Zoo-Code-Org#404.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review. 📜 Recent review details🧰 Additional context used📓 Path-based instructions (5)Treat model, provider, MCP, path, command, and tool data as untrusted.⚙️ CodeRabbit configuration file Files:
Require regression coverage at the lowest valid harness with behavior-focused assertions, including relevant negative, error, false/unset, and boundary cases.⚙️ CodeRabbit configuration file Files:
Check strict typing and exhaustive behavior across normal, boundary, error, cancellation, retry, and compatibility paths.⚙️ CodeRabbit configuration file Files:
Verify extension/webview contracts, cancellation and error propagation, VS Code lifecycle correctness, and behavior under retries and partial failure.⚙️ CodeRabbit configuration file Files:
Act as an adversarial second-opinion reviewer.⚙️ CodeRabbit configuration file Files:
🔇 Additional comments (3)
📝 SummarySummary by CodeRabbit
WalkthroughThe provider utilities now support abort-aware promise and model resolution. Abort errors are normalized and classified only from ChangesAbort-aware resolution
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Feature Merge Risk: ⚪ Minimal · up to The new shared cancellation helpers are covered for their intended abort and settlement paths, with no current integration risk identified. The change is ready to merge. 🚥 Pre-merge checks | ✅ 7 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (7 passed)
Full details: Regression EvidenceExplanation The new Resolution Add a focused test for
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Review statusThanks for contributing. This comment tracks the review sequence and the next action. Current step: Awaiting fresh human maintainer or CODEOWNER approval. Automated review is complete for the latest commit but does not replace human approval. Review-state labels are managed by this workflow; do not edit them manually. |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Shared-util piece of the abort-signal series (round 1): extends
src/api/providers/utils/abort-signal.tswith the helpers the gateway providers use to run request phases inside a cancellation scope.resolveModelWithAbort(fetchModel, abortSignal, providerName): runs model resolution inside a cancellation scope - a pre-aborted signal fast-fails before any catalog/SDK work, arejectOnAbortrace settles the lookup with the provider AbortError when the signal fires mid-resolution, and abort-flavored lookup failures are normalized; any other resolution failure propagates unchanged.rejectOnAbort(pending, signal, providerName): the race primitive - rejects withcreateAbortError(providerName)when the signal fires beforependingsettles; the abort listener detaches whenpendingsettles, so a task-scoped signal does not accumulate listeners.createAbortError(providerName): fresh error satisfying the Task.ts abort contract (name === "AbortError", message ending in "aborted").isRequestAborted(error, signal?): wider abort detection - an aborted signal, a DOMAbortError, the OpenAI/Anthropic SDKAPIUserAbortError(name check), or the exact "Request was aborted." message. The name/message checks now require a realErrorinstance, so a plain object that merely looks like an abort propagates unchanged.throwIfAborted- dead code: nothing on main (or in the sibling abort PRs) calls it; it was exercised only by its own unit tests.Tests: unit specs for all four helpers plus the new
settle-guardtest utility.Series and unit
Unit 1/3 of the #1295 split (content source:
62f596c5d). Merge order: this unit first, then the opencode-go unit, then the unbound/vercel/zoo unit. No provider behavior changes in this unit.Part of the abort-signal series (round 1). Builds on #674, #901, #1008. Addresses #404.
Review response (maintainer review of #1295)
mergeAbortSignalAndTimeout,mergeAbortSignalsuntouched) plus the new helpers;throwIfAbortedwas removed as dead code andisRequestAbortedwas tightened with theinstanceof Errorrequirement (kill-tested: plain-object abort look-alikes propagate unchanged).resolveModelWithAbort; each provider unit exercises it end-to-end (pre-aborted fast-fail, mid-resolution race, normalization, no-signal pass-through).Evidence
rejectOnAbortsettle-handler pair, with an event-fires-once equivalence proof), 0 Survived / 0 NoCoverage / 0 Timeout