Hallo,
I found the following bug and it is reproducible.
First, I am using Apollo Angular, but this is a problem within Apollo Client so it should be also an issue with React.
Intended outcome:
I am an Apollo Angular and use a watched query to fetch a list of items from the backend server. In the application there is a button to allow the user to refresh the items (this calls refetch() on the watched query).
This should work anytime, even if there has been an error on a previous refetch before.
I subscribed to the query like this:
this.query$.subscribe(result => {
if (result.errors)
console.error("Query failed");
else
console.info("Query succeeded!");
});
The problem is: when refetch is called and is successful, the subscription function will be called. But as soon as there is one refetch that fails, the subscription function won't be called anymore for successful refetches. For failed refetches, the subscription will always be called, even after one failed refetch.
Important for reproduction:
Cause of the bug
I debugged into Apollo Client and found out what's going on:
In the QueryManager there is a check if the previous result is different to the current. This is stored in the local variable isDifferentResult.
In this situation, isDifferentResult will be false for a successful refetch after a failed one.
There is a related bug https://github.com/apollographql/apollo-client/pull/1601 that has fixed the same problem, but not for all cases as I can see now. It introduced the variable previouslyHadError, but that one is also false.
So, the observer won't be called in this piece of code:
if (isDifferentResult || previouslyHadError) {
try {
observer.next(maybeDeepFreeze(resultFromStore));
The previouslyHadError is not set because of the error policy set to "all" in my case.
I suppose this bug could be fixed by changing the assignment of isDifferentResult to:
const isDifferentResult = !(
lastResult &&
resultFromStore &&
lastResult.networkStatus === resultFromStore.networkStatus &&
lastResult.stale === resultFromStore.stale &&
// We can do a strict equality check here because we include a `previousResult`
// with `readQueryFromStore`. So if the results are the same they will be
// referentially equal.
lastResult.data === resultFromStore.data &&
lastResult.errors === resultFromStore.errors // <-- NEW
);
Or by playing around with the code that sets previouslyHadError...but I'm not that into the Apollo Client code to make a well-informed decision.
Version
Issue Labels
I found a simple workaround:
Before calling refetch(), I now just call resetLastResults() on the query.
Any actual fixes for this? It is more than ridiculous that subscribe isn't called on refetch...
For me it seems sporadic too. I got 2 queries, Follow and Unfollow. I can run both in sequence without an issue. Whenever I try to do refetch though, subscribe is sometimes (but rarely) called.
Thanks for reporting this. There hasn't been any activity here in quite some time, so we'll close this issue for now. If this is still a problem (using a modern version of Apollo Client), please let us know. Thanks!
Most helpful comment
I found a simple workaround:
Before calling refetch(), I now just call resetLastResults() on the query.