apollo-client: client.resetStore() - Uncaught (in promise) Error when server returns an error

When I use client.resetStore() on logout, and the server returns an error for my current user query (as it should because their is no logged in user), Apollo throws an Uncaught (in promise) Error.

Note that if I reload the page instead of reset the store (or the current user query runs with no logged in user in the normal flow of the app), the server returns its error, but there is no Uncaught (in promise) Error.

Using: apollo-client 0.7.3, and react-apollo 0.8.1

Here’s the stack trace:

Uncaught (in promise) Error: GraphQL error: User is not authorized to access path: viewer,user
    at new ApolloError (apollo.umd.js:1498)
    at apollo.umd.js:2722
ApolloError @   apollo.umd.js:1495
(anonymous) @   apollo.umd.js:2722
Promise.reject (async)      
(anonymous) @   apollo.umd.js:2748
Promise (async)     
(anonymous) @   apollo.umd.js:97
Promise (async)     
HTTPFetchNetworkInterface.fetchFromRemoteEndpoint   @   apollo.umd.js:81
(anonymous) @   apollo.umd.js:90
Promise.resolve (async)     
HTTPFetchNetworkInterface.query @   apollo.umd.js:90
Deduplicator.query  @   apollo.umd.js:1977
(anonymous) @   apollo.umd.js:2708
QueryManager.fetchRequest   @   apollo.umd.js:2706
QueryManager.fetchQuery @   apollo.umd.js:2434
ObservableQuery.refetch @   apollo.umd.js:1613
(anonymous) @   apollo.umd.js:2510
QueryManager.resetStore @   apollo.umd.js:2507
ApolloClient.resetStore @   apollo.umd.js:2963
User._this.handleLogout @   User.js:11

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 2
  • Comments: 16 (8 by maintainers)

Most upvoted comments

For my own case I found two possible solutions while using Apollo 3.3.21

Option A) adding a .catch on the resetStore

     <button
          onClick={() => {
            Cookie.remove("token");
            client.resetStore().catch((e) => {
              // do nothing or something or whatever you want
            });
          }}
        >
          Logout
    </button>

Option B) Instead of client.resetStore() use client.cache.reset() which clears the cache but does not refetch queries

        <button
          onClick={() => {
            Cookie.remove("token");
            client.cache.reset();
          }}
        >
          Logout
        </button>

@calebmer Is there a way to have it not refetch? For example when logging out, I sort of just want to kill everything. I’m running into issues where logging out -> logging in -> still has cached data from the logged out user.

Not sure if intentional, but I heard resetStore got some fixes recently, however I’m stuck on 0.5.21 due to the upgrading breaking updateQueries.

Sure. When resetting the store in QueryManager#resetStore we re-fetch every query we know of. ObservableQuery#refetch returns a promise and I bet that is where are uncaught error is coming from 😉

To fix this just have QueryManager#resetStore return a promise that resolves when all of the queries have been re-fetched and rejects when one of the queries rejects.

Anyone watching the queries that error will be notified through their observer.error handle. That’s probably where the error should really be handled. This change just allows the user to prevent unhandled promise rejections.

Another option would be to just ignore all errors from refetch as the errors will likely be handled elsewhere, but I think returning a promise is a better choice as it also allows the user to know when the reset has completed.