Skip to content
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

'ObservableQuery with this id doesn't exist: id' on unmounted component #4114

Closed
janmisek1 opened this issue Nov 8, 2018 · 34 comments
Closed

Comments

@janmisek1
Copy link

janmisek1 commented Nov 8, 2018

Actual outcome:

Hello,

when any of my react native componets start fetching data and is unmounted befor finish, app yell
: Possible Unhandled Promise Rejection (id: 0): Error: ObservableQuery with this id doesn't exist: 11

There is any posibility how to prevent/catch/fix it? Its only bad setting or bug?

thanks

Versions

npx: installed 1 in 1.561s

  System:
    OS: Linux 4.15 Ubuntu 18.04.1 LTS (Bionic Beaver)
  Binaries:
    Node: 10.10.0 - /usr/local/bin/node
    Yarn: 1.10.1 - ~/.yarn/bin/yarn
    npm: 6.4.1 - /usr/local/bin/npm
  Browsers:
    Chrome: 69.0.3497.100
    Firefox: 63.0
  npmPackages:
    apollo-cache-inmemory: 1.3.6 => 1.3.6 
    apollo-cache-persist: ^0.1.1 => 0.1.1 
    apollo-client: ^2.4.5 => 2.4.5 
    apollo-link: ^1.2.3 => 1.2.3 
    apollo-link-context: ^1.0.9 => 1.0.9 
    apollo-link-error: ^1.1.1 => 1.1.1 
    apollo-link-http: ^1.5.5 => 1.5.5 
    apollo-link-logger: ^1.2.3 => 1.2.3 
    react-apollo: ^2.2.2 => 2.2.4 
@sandorvasas
Copy link

sandorvasas commented Nov 20, 2018

+1
This happens with the graphql HOC for us. Not saying the <Query/> component doesn't do it, we use the graphql HOC 95% of the time.

@rlancer
Copy link

rlancer commented Nov 30, 2018

Getting this in our production environment but not our staging or local, no idea how to fix.

Update: Issue was caused by an error in a related component, the error boundary caused the Query component to become unmounted.

@bsbechtel
Copy link

I was seeing this, and it ended up being that I was resetting limit variables on a paginated query that uses fetchMore. I was doing it on a child component componentDidUnmount however (so it would be reset when you go back to the screen with the list). This was causing the query to refetch and immediately disappear. Not sure if that's helpful for your issue or not, but figured I'd share!

@sghall
Copy link

sghall commented Dec 7, 2018

I am also getting ObservableQuery with this id doesn't exist: 13 during SSR and I cannot figure out what the problem is. In my cases it happens when I use the HOC and try to subscribeToMore AND use the updateQuery option. It works fine in the browser but on the server I get this error. If I remove the updateQuery it works fine on the server. Any ideas what to look at?

@Ethaan
Copy link

Ethaan commented Jan 4, 2019

As @sghall i'm getting this also using SSR with updateQuery, randomly

@redreceipt
Copy link

Getting this in our production environment but not our staging or local, no idea how to fix.

Update: Issue was caused by an error in a related component, the error boundary caused the Query component to become unmounted.

@rlancer can you elaborate on your solution a little? Trying to diagnose a Sentry error.

@rlancer
Copy link

rlancer commented Jan 14, 2019

@redreceipt we have a infinite scroll for our main feed with a side bar that also has an infinite scroll, we were only using Apollo to power our main feed, the sidebar ended up crashing and the only error we saw was 'ObservableQuery with this id doesn't exist: id' on unmounted component, it turned out the sidebar was within the same parent error boundary as the main feed which so when it crashed it caused our main feed to unmount hence causing the error.

@jhd124
Copy link

jhd124 commented Apr 15, 2019

I am also seeing this message. I guess it's because the query response comes back from my server, but the Query HOC has already unmounted, consequently, Apollo Client doesn't know which query to update.

@rlancer
Copy link

rlancer commented Apr 15, 2019 via email

@spilist
Copy link

spilist commented Apr 28, 2019

This error happens to me in the following situation. (always reproducible)

  1. In a page A which uses a query Q, click a button to fetchMore. This page has a search param in URL to get query result with different variables.
  2. Before fetchMore finishes, move to another page A' which uses the same query Q but with different search params.
  3. error ObservableQuery with this id doesn't exist happens.

I found a solution for this case; setting different keyfor <Query /> component (using search param) removes the error. If I understood correctly, it makes react to render a new <Query /> component, so it won't try to update the previous query.

I'm not sure but also suspecting that this not only happens for fetchMore, but may happen between two components with the same query in some conditions. Unfortunately, I haven't reproduced and found a solution for this "general" case.

Hope this helps.

@valerybugakov
Copy link

We have the same issue. It would be great for Query to track if the underlying component is unmounted.

@joebernard
Copy link
Contributor

I am seeing this issue using the aws-appsync client that uses apollo-client 2.4.6. The original report here uses 2.4.5. Can someone confirm this is still an issue with the latest version of apollo-client (currently 2.5.1)?

@ducarroz
Copy link

Hitting this issue when the variables of my <Query> changes while a fetchMore is still in progress.

@klaaspieter
Copy link

Still hapens for me in 2.6.0.

@dan-cooke
Copy link
Contributor

dan-cooke commented May 27, 2019

Yeah this happens for me in 2.5 when I unmount/remount my HOC. It kind of makes sense but I am lost as to how to fix it.

Normal Behaviour

  1. HOC (graphql wrapped component) is mounted, with variables offset, limit, orderBy and filter passed from props.

    • User can interact with the HOC changing any of these variables using internal state and fetchMore side effects on each state variable. Every query completes.

    • Even when props are changed and the initial HOC query fires again - the fetchMore is still in sync with this query id.

  • Component mounts for the first time , Network Status: 1 (loading)
  • Query completes, and data is populated into the UI, Network Status: 7 (ready)
    ... waits for user interaction
  • User clicks a header to sort the data, fetchMore is called, Network Status: 3 (fetchMore)
  • Query completes, Network Status: 7 (ready)

Abnormal Behaviour

  1. HOC (graphql wrapped component) is mounted, with variables offset, limit, orderBy and filter passed from props.
  2. User causes HOC to be unmounted, and remounted.
  • Component mounts for the first time , Network Status: 1 (loading)
  • fetchMore is called before the component is (ready), Network Status: 3(fetchMore)
  • Query errors with 'ObservableQuery with this id doesn't exist: id', Network Status: 8 (error)

This screenshot, shows normal behaviour on the top half and abnormal behaviour after the second mount.
Screenshot 2019-05-27 at 14 23 33

What is happening

It looks like the fetchMore query is referring wrong ObservableQuery id upon remount. I'm guessing when a graphql component is unmounted the ObservableQuery is destroyed.

However it seems that the fetchMore is still referring to this destroyed query.

Workaround for my case

  • I could extract all my state into the parent component, remove all fetchMore queries and simply refire the HOC query when any props change. Although I really don't like this approach, as the logic should not be extracted to the parent component.

Question

Is it possible to fully "cleanup" a graphql component when it is unmounted? ie. the fetchMore's should only refer to the most recent query, not a previous destroyed query.

@dylanwulf
Copy link
Contributor

I'm having an issue which I think may be related to this. When a query is loading and the component unmounts before the query completes, then the network request gets cancelled (normal behavior). But when a fetchMore is loading and the component unmounts before it completes, then the network request does not get cancelled (abnormal behavior).

@jounii
Copy link

jounii commented Jun 14, 2019

Having faced the same issue with fetchMore. Still thinking how to fix it.. the underlaying component (data search screen) can be unmounted by user by selecting or cancelling search value while fetchMore is still fetching data, be that automatic fetchMore or infinite scroll, the problem arises from the fact that the backend responses are a bit slow.

Workaround would be to disallow/delay unmount until fetchMore completes or maybe somehow catch and handle these specific errors outside from raising problem.

@jounii
Copy link

jounii commented Jun 14, 2019

Found solution.

The error is raised by Promise returned by the fetchMore call. So, you have to catch that.

Insted of just calling (as in all examples):

fetchMore({variables: {...}, updateQuery: ()=>{...}})

Instead do (in ES6 syntax):

try { await fetchMore({variables: {...}, updateQuery: ()=>{...}}) catch { }

Then the async error thrown after component unmount is catched. The updateQuery function is not called as error is thrown before that. You could also handle the error a bit better, if more finer error control is needed than just supressing all errors.

@dylanwulf
Copy link
Contributor

@jounii That works for me, thank you! I wish there was a way to cancel the fetchMore request though.

@amille14
Copy link

@spilist thanks! adding a unique key to my query component (or in my case to my query hook, since i'm using react-apollo-hooks) fixed the issue

@TheoMer
Copy link

TheoMer commented Aug 23, 2019

@sghall @Ethaan Did you guys manage to resolve this issue? I'm getting the exact same issue as you (randomly works), with the error jumping between Invariant Violation: ObservableQuery with this id doesn't exist: 7 and Uncaught Invariant Violation: ObservableQuery with this id doesn't exist: 51.

I'm using the following packages:

apollo-client: 2.6.3
react-apollo: 2.5.8
next: 9.0.0
react: 16.8.6

@Hatko
Copy link

Hatko commented Aug 29, 2019

Getting the same error

@GiancarlosIO
Copy link

👀

@leandroFernandez94
Copy link

In my case I had a list of components sharing a connected query and found that this line was causing the problem https://github.com/apollographql/apollo-client/blob/master/packages/apollo-client/src/core/ObservableQuery.ts#L601

if you keep at least one component always subscribed to the query you shouldnt get that error

@jmurret
Copy link

jmurret commented Jan 14, 2020

@amille14 Do you have a snippet of how you added a key to the react hook?

@digitalmaster
Copy link

Second: Also curious to know how you add key to a react hook?

@digitalmaster
Copy link

For those curious: Wrapping hook in HOC, and then passing a key prop solved the issue for me.

const Fetcher = ({children}) => {
  const result = myHook();
  return children(result);
}

And then render like so

<Fetcher key={someUniqueKey}>
  { results => <SomeComponent results={results} /> }
</Fetcher>

@amille14
Copy link

@jmurret @digitalmaster I simply passed a key in to the useQuery hook like this:

const { data, loading, error } = useQuery(myQuery, { variables: { ... }, key: 'some key' })

You can also use a key prop on apollo's Query/Mutation components like so:

<Query query={myQuery} key='some key' variables={{ ... }}>
  ...
</Query>

Note that for the hooks I was using the react-apollo-hooks package. This was before Apollo released official support for hooks. I have no idea if passing a key to Apollo's hooks will work the same way, though I do know that their hooks are based on that package so it might work.

@digitalmaster
Copy link

digitalmaster commented Jan 23, 2020

@amille14 Thanks a ton for sharing that context. Looks like they do differ. Doesn't look like 'key' is part of Apollo React Hook:

TypeScript Error:

'key' does not exist in type 'QueryHookOptions<Data, Record<string, any>>'

Although this would be a nice feature.

@StefanSmith
Copy link

Hi,

We are seeing the issue when running tests in Jest because (I think) Jest fails when exceptions are thrown in promises but not caught. For us, it happens with the graphql() HOC when the fetchMore() has been invoked but its result arrives after the component has unmounted.

For now, we have applied the following patch (to apollo-client v2.4.6) as a workaround, simply to stop Jest seeing the uncaught exception:

diff --git a/node_modules/apollo-client/bundle.umd.js b/node_modules/apollo-client/bundle.umd.js
index 63a5534..71b64e7 100644
--- a/node_modules/apollo-client/bundle.umd.js
+++ b/node_modules/apollo-client/bundle.umd.js
@@ -287,7 +287,7 @@
                     });
                 });
                 return fetchMoreResult;
-            });
+            }).catch(() => {});
         };
         ObservableQuery.prototype.subscribeToMore = function (options) {
             var _this = this;

Note, we are on apollo-client v2.4.6 because we are using aws-appsync which requires this version!

@gudwnsdl88
Copy link

gudwnsdl88 commented Feb 25, 2020

I just add key props with my Query Component

This is working!

my cord ->


{({ subscribeToMore, data: getNearbyRide }) => {
const rideSubscriptionOptions: SubscribeToMoreOptions = {
document: SUBSCRIBE_NEARBY_RIDES,
updateQuery: this.handleSubscriptionUpdate
};
subscribeToMore(rideSubscriptionOptions);
return (...~~~)

@paulgrieselhuber
Copy link

paulgrieselhuber commented Mar 23, 2020

Migrating from react-apollo-hooks to the official Apollo package squared this for me (ht @amille14 )

spinningarrow added a commit to spinningarrow/goldspot that referenced this issue Apr 4, 2020
apollographql/apollo-client#4114

Steps to reproduce:

1. Go to Library
2. While it is loading, go to another view
adamsoffer added a commit to livepeer/livepeer-monorepo that referenced this issue May 15, 2020
This commit wraps the `fetchMore` call in a try catch to avoid the runtime error thrown by apollo when navigating from the history view to the campaign view or any other route for that matter.
apollographql/apollo-client#4114
@ayushnawani
Copy link

I am also facing this issue, any solution alternative to catching the error,
also not sure how to use the unique key, since on mount and unmount my same query is gonna call withs the same key name?

@hwillson
Copy link
Member

A lot of the Apollo Client internals have changed since v3 was launched. We recommend trying a more modern version of @apollo/client. Let us know if you're still encountering this issue. Thanks!

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests