feat(interceptors): add signal interceptor#5541
Open
Arman-Luthra wants to merge 1 commit into
Open
Conversation
Add a new interceptor that aborts the dispatched request when the signal dispatch option is aborted, per the direction in nodejs#3276. Supports both AbortSignal and EventEmitter-style signals, aborts with signal.reason when available (RequestAbortedError otherwise), and removes the abort listener once the request completes, errors or is upgraded. A signal that is already aborted fails the dispatch before the request reaches the server.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5541 +/- ##
==========================================
+ Coverage 93.45% 93.46% +0.01%
==========================================
Files 110 111 +1
Lines 37376 37470 +94
==========================================
+ Hits 34928 35020 +92
- Misses 2448 2450 +2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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.
This relates to...
Closes #3276
Rationale
#3276 asks for
AbortSignalhandling to be available as an interceptor. Following the direction given in the issue thread, this adds a completely newsignalinterceptor shaped likeinterceptors.responseError: when thesignaldispatch option is aborted, the request is aborted and the abort listener is cleaned up.This is mainly useful when calling
dispatch()directly with a custom handler, where today every caller has to wire up (and remember to remove) their own abort listener the way the API-layer handlers inlib/apido. The existing API-layer signal handling is intentionally left untouched.Changes
lib/interceptor/signal.js, exported asinterceptors.signalAbortSignalandEventEmitter-style signals (same contract as thesignaloption of the API methods, validated the same way)signal.reasonwhen available,RequestAbortedErrorotherwiseRequestHandleronResponseEnd,onResponseErrorandonRequestUpgrade, so long-lived signals do not accumulate listenersonRequestStartso composing withretry()keeps aborting the active attemptdocs/docs/api/Interceptors.md,docs/docs/api/Dispatcher.md), types (types/interceptors.d.ts) and type tests includedFeatures
interceptors.signal()interceptorBug Fixes
N/A
Breaking Changes and Deprecations
N/A
Testing
test/interceptors/signal.jsexercises the interceptor throughclient.dispatch()with a bare handler rather thanclient.request(), since the API-layer handlers already implement their own signal handling and would mask what the interceptor does. Covered: pre-aborted signal (exact reason propagated, request never reaches the server, onlyonResponseErroris delivered), mid-response abort,EventEmitter-style signals, listener removal after completion and after an error (asserted viagetEventListeners/listenerCount), pass-through when no signal is provided,InvalidArgumentErrorfor non-signal values, and compatibility withclient.request().npm run lint,npm run test:interceptorsand the TypeScript checks pass locally (the pre-existing zstd decompress test is skipped locally as Node 22.14 lackszlib.createZstdCompress).Status