`AbortError: BodyStreamBuffer was aborted` when unsubscribing multipart subscription (BaseHttpLink)
Issue Description
Description
Calling subscription.unsubscribe() during a multipart HTTP subscription causes Uncaught (in promise) AbortError: BodyStreamBuffer was aborted. Related to #13125.
Root cause: The Observable teardown in BaseHttpLink calls controller.abort() when the subscription is unsubscribed. At that moment readMultipartBody is still consuming response.body via reader.read(). The abort kills the stream → reader.read() rejects with AbortError → .catch() propagates it → uncaught.
return () => {
if (controller) controller.abort(); // ← triggers AbortError in readMultipartBody
};Proposed fix: In src/link/http/BaseHttpLink.ts – track intentional teardown with a flag:
let didAbort = false;
return new Observable((observer) => {
// ... fetch setup ...
currentFetch(...)
.then(...)
.catch((err) => {
cleanupController();
if (didAbort) return; // Intentional abort from teardown
observer.error(err);
});
return () => {
didAbort = true;
if (controller) controller.abort();
};
});Reproduction
Consumer code – subscription with next handler that unsubscribes on error:
const subscription = client.subscribe({
query: SomeDocument,
variables: { input: { ... } },
}).subscribe({
next: ({ data, error }) => {
if (error) {
subscription.unsubscribe(); // ← triggers AbortError
setLoading(false);
// handle error...
} else {
setData(data);
}
},
complete: () => { ... },
});Steps: Run multipart subscription (MSW mock or real server) → receive chunk with GraphQL error → subscription.unsubscribe() in next → AbortError in console.
Workaround: Don't call subscription.unsubscribe() in the error branch; let the stream complete naturally.
Environment
@apollo/client: 4.1.4- Multipart HTTP subscriptions (GraphOS)
- Chrome
Link to Reproduction
https://codesandbox.io/p/github/ItaiYosephi/apollo-abort-error-repro/main?import=true
Reproduction Steps
Open the reproduction
- CodeSandbox: https://codesandbox.io/p/github/ItaiYosephi/apollo-abort-error-repro
- Or clone and run locally:
git clone https://github.com/ItaiYosephi/apollo-abort-error-repro.git cd apollo-abort-error-repro npm install npm start
Open the app in the browser (e.g. http://localhost:3000 or the CodeSandbox preview).
Click "Start subscription" to start the multipart HTTP subscription.
Check the browser console – you should see:
Uncaught (in promise) AbortError: BodyStreamBuffer was aborted
What happens: The MSW mock returns a multipart response with an error chunk. When the next handler receives the error, it calls subscription.unsubscribe(). That triggers the teardown in BaseHttpLink, which calls controller.abort() while readMultipartBody is still consuming the stream, causing the uncaught AbortError.
@apollo/client version
4.1.4
Source: apollographql/apollo-client