-
Notifications
You must be signed in to change notification settings - Fork 749
Description
Question
Summary
When a running query task is cancelled, Apollo currently throws ApolloClient.Error.noResults instead of propagating CancellationError. This happens when the query has not yet produced any results—for example when using .networkOnly or when the cache is empty.
The error description for ApolloClient.Error.noResults is:
The operation completed without returning any results. This can occur if the network returns a success response with no body content.
If using a `RequestChainNetworkTransport`, this can also occur if an interceptor fails to pass on the emitted results.
I’ve attached a simple project and a video that demonstrates the issue where cancellation consistently results in .noResults.
output.mp4
Environment
- iOS version: 26.1
- Xcode version: 26.1.1 (17B100)
- macOS version: 26.1 (25B78)
- Apollo iOS version: 2.0.3
- Device / Simulator: 17 Pro
Where the behaviour occurs
In RequestChain, within:
private func kickoffRequestInterceptors(
request initialRequest: Request,
continuation: ResultStream.Continuation
) async throws
The relevant code path is:
var didEmitResult: Bool = false
for try await response in resultStream.getStream() {
try Task.checkCancellation()
try await writeToCacheIfNecessary(response: response, for: finalRequest)
continuation.yield(response.result)
didEmitResult = true
}
guard didEmitResult else {
throw ApolloClient.Error.noResults
}
Observed behaviour
- If at least one result is emitted before cancellation, Apollo would correctly propagate
CancellationError. - If zero results are emitted before cancellation, the loop exits and falls through to the guard, which throws
.noResults, effectively squashing the cancellation error.
Question
Is this behaviour intended? Would it make sense for Apollo to also check Task.isCancelled before throwing .noResults, so cancellations result in CancellationError?
This would allow us to reliably distinguish between (since the noResults error description doesn't match the behaviour):
- “Cancelled before producing a result”
- “Completed with no results”
Thanks!