-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2.0 not clearing error after refetch #2513
Comments
BTW I have options set to |
@msmfsd would you be able to create a reproduction of this issue? I think I can reproduce it as well, but it would save on time if you had something I could take a look at? |
@jbaxleyiii yep will have a look now |
@jbaxleyiii error template is here: https://github.com/msmfsd/apollo-error-tmpt-pr-2513 NOTE: it was tricky to trigger an realistic error off and on without an external server.. |
@msmfsd @jbaxleyiii I got the same issue. It's pretty easy to reproduce it.
Quick fix is to refresh the page. |
I got the same bug for |
This issue prevents letting users retry failed queries manually. I would assume this is a really common use case. Any ETA on a fix? |
This is a really critical bug because it means that refetches won't work after a network status interruption. |
Same here! |
@dotansimha I forget where I found this, but I read on another github thread somebody suggesting the following workaround: Overwrite the You should be able to find the section in react-apollo.browser.umd.js (in the react-apollo package) that contains these lines: else if (error_1) {
assign(data, (this.queryObservable.getLastResult() || {}).data);
} You can change that to be this: else if (error_1) {
assign(data, (this.queryObservable.getLastResult() || {}).data, {
retry: () => {
this.unsubscribeFromQuery();
this.queryObservable = null;
this.previousData = {};
this.updateQuery(this.props);
if (!this.shouldSkip(this.props)) {
this.subscribeToQuery();
}
}
});
} Then if your query results in a network error, you can at least call Instead of overwriting node_modules, the way I set this up was to drop a file into a folder in my project called Now, you just import graphql from The other thing you can do is use the |
Thanks @adambom ! I used your workaround and it works! (If someone else needs it, I published is as |
Glad I could help. Keep in mind that if you're doing something like this: componentWillReceiveProps(nextProps) {
if (nextProps.data && nextProps.data.retry) {
nextProps.data.retry();
}
} You'll get an infinite loop of retries if you're not careful. You can either throttle the |
@jbaxleyiii can the above be used as fix for this issue? |
Hi @jbaxleyiii, do you have any ideas for the right solution for this? The |
Ok, I've spent many many hours debugging this now with no luck whatsoever. I've checked both I could really use some help from someone who understands this codebase better. This is a serious issue, and will affect any user who may have a spotty internet connection. To summarize the problem and how to reproduce it: after receiving a network error, components wrapped with the The way you can reproduce this is to set up one component with a query, wrapped in the Then turn the server back on and refetch again. In your server logs you should see that the query is being run. However, the component will not be updated with data from the server (i.e. render is not called - the component does not receive new props). From what I can gather, after the refetch completes, I tried to address this by commenting out Indeed, that prevents the listeners from being removed, but when the listener is called ( |
Ok for anyone following this issue, I have an improved workaround to the one I mentioned earlier. Instead of adding a else if (error_1) {
const refetch = data.refetch;
assign(data, (this.queryObservable.getLastResult() || {}).data, {
refetch: (refetchOptions) => {
this.unsubscribeFromQuery();
this.queryObservable = null;
this.previousData = {};
this.createQuery(refetchOptions, this.props);
if (!this.shouldSkip(this.props)) {
this.subscribeToQuery();
}
return new Promise(function (r, f) {
_this.refetcherQueue = { resolve: r, reject: f, args: refetchOptions };
});
}
});
} Then you can just continue to call @dotansimha would you mind changing the -- edit 1 -- I published this change under the name -- edit 2 -- |
Thanks @adambom you are a life saver. Replacing my react-apollo with react-apollo-temp-adambom Fixed the issue. |
@jbaxleyiii, @stubailo, @helfer, @Poincare (or any of the other mainteners) would you be open to a PR for this fix? I don't think I've cured the problem, only treated the symptom, nor do I think I've found the optimal fix. That said, I'd like to help others who are having this problem and I'd really appreciate it if someone more knowledgeable with this codebase could chime in. Thanks! |
I have a similar very closely related issue to @adambom's which can be found in our storybook. Click "next page" then "retry", then all subsequent paging will be broken. Code can be found in the repo, the Potentially this happens due to a mixture of issues. We're not doing paging correctly, not refetching correctly and/or the bugs highlighted above. I appreciate this criss-crosses When the error occurs, the query is "torn down" and the @adambom's solution above works because it creates a whole new query with new subscriptions and Also happy to contribute to a PR but just need direction on how it's supposed to work.
As a side note,
This again may be the result of our use of |
@alewiahmed I don't think I'll have time too look at it this week. The fix I issued specifically only deals with refetch and nothing more. If this is urgent, I would suggest you take a look at the dataForChild method of the graphql higher order component and try something similar to what I did with refetch. If you find a fix, I'm more than happy to publish it in my temp package. |
replace react-apollo with npmjs.com/package/react-apollo-temp which is a fork that provides a workaround to this issue apollographql/apollo-client#2513
replace react-apollo with npmjs.com/package/react-apollo-temp which is a fork that provides a workaround to this issue apollographql/apollo-client#2513
I am running into this issue as well.. strangely enough it seems like the unit test for this scenario was removed some months ago. The issue is fundamentally caused by ES6 Observables terminating the stream when an error is sent to an observer. In this case, any kind of error in the query causes the react-apollo component to get dropped (from here to here to here), and the subsequent teardown of the query is just a further consequence. The components themselves don't contain much subscription logic beyond the mount/unmount lifecycle and thus remain unaware the queries were torn down. It seems like the subscription logic for react components might need further consideration, or perhaps a different way to handle error conditions. In either case, here is my own short-term workaround which should serve as a drop-in replacement for the normal const MyGraphQL = (...args) => Component =>
class extends graphql(...args)(Component) {
dataForChild() {
const data = super.dataForChild();
if (data.refetch && data.error) {
data.refetch = (...args) => {
this.unsubscribeFromQuery();
const { lastError, lastResult } = this.queryObservable;
// If lastError is set, the observable will immediately
// send it, causing the stream to terminate on initialization.
// We clear everything here and restore it afterward to
// make sure the new subscription sticks.
this.queryObservable.resetLastResults();
this.subscribeToQuery();
Object.assign(this.queryObservable, { lastError, lastResult, isTornDown: false });
return this.queryObservable.refetch(...args);
};
}
return data;
}
}; |
Great work @wdimiceli - can you explain more specifically how you propped it in to your codebase? Did you create a lib or a hoc? I'm keen to test it on a live application. |
@msmfsd In my case it was pretty easy because my components are already using a wrapped version of I'm sending a PR which incorporates the approach I took plus a unit test that demonstrates the issue. Would love to get some feedback and/or get it merged asap (...or if I did it entirely wrong because this is my first github PR...). |
Thanks @wdimiceli I monitor this issue closely so will review for sure. |
@adambom There's another similar error, where a second user can see the error returned from the first user's query. Not refetch, but very similar concept. |
@wdimiceli Can confirm his solution works |
Now that this has been fixed in #1531, any idea on when a new release will be published to npm? |
@Dremora apollographql/react-apollo#1531 <-- the PR is for react-apollo, not apollo-client, better to ask there. |
This was fixed in apollographql/react-apollo#1531. Closing - thanks! |
was it part of 2.1.4 |
Still having this issue on "apollo-client": "^2.6.8" |
Intended outcome:
data.error should be cleared after successful refetch.
Actual outcome:
after error a successful refetch does not clear the error.
(In fact I dont think query data is set to undefined on error either, it also retains previous response if there was one. Not sure if that caching and is possibly expected on network-only calls?)
How to reproduce the issue:
Version
The text was updated successfully, but these errors were encountered: