wsLink: AbortSignal on operations is ignored — abort does not cancel in-flight requests or subscriptions
Description
The WebSocket link does not honor the AbortSignal passed with an operation. Calling abort() on the signal has no effect on in-flight queries, mutations, or subscriptions sent through wsLink.
Repro
const controller = new AbortController();
const result = trpc.someQuery.query(undefined, { signal: controller.signal });
controller.abort(); // has no effect on the WS requestContrast with httpSubscriptionLink which correctly tears down the subscription when the signal fires.
Root cause
wsClient.ts:235 calls signal?.removeEventListener('abort', abort) in the cleanup path — but there is no corresponding signal?.addEventListener('abort', ...) anywhere in the wsLink source. The abort listener was never registered; only the cleanup was scaffolded.
This appears to be an incomplete implementation from the v11 refactor (PR #6223) which plumbed signal into the request function but only wired the teardown half.
Verified via the current source — signal is received at lines ~186 and ~190, but only removeEventListener is called (line 235); no addEventListener call exists anywhere in the wsLink directory.
Expected behaviour
When the caller's AbortSignal fires:
- In-flight queries/mutations: the pending request should be cancelled and the promise rejected with
AbortError - Subscriptions: the subscription should be torn down
Possible fix
In the request() function, after the early-exit check for signal?.aborted, add:
signal?.addEventListener('abort', teardownFn, { once: true });and ensure teardownFn removes the listener when the operation completes normally (which is what the existing removeEventListener call at line 235 already does — it just has no matching registration).
Source: trpc/trpc