From 93bda88ff086395a60aeabc6aaa216173aa7e277 Mon Sep 17 00:00:00 2001 From: Hugh Willson Date: Mon, 17 Jun 2019 17:57:16 -0400 Subject: [PATCH] Reset query store errors via `ObservableQuery.resetQueryStoreErrors` (#4941) * Reset query store errors via `ObservableQuery.resetQueryStoreErrors` React Apollo relies on the `ObervableQuery->getCurrentResult` method to retrieve query results to show within its components. When an error occurs while fetching results, that error is stored in the query store that each `ObservableQuery` instance is configured to use. Unfortunately, `getCurrentResult` will only retrieve subsequent results if no error exists in the query store. `ObservableQuery` doesn't currently provide a way to clear out query store errors, which means when React Apollo originating requests that cause an error occur, the error is stored, and future valid requests can no longer be processed. This commit adds a `resetQueryStoreErrors` method to the `ObservableQuery` public API, that will allow React Apollo (and other consumers) to be able to clear out query store errors. Related to: https://github.com/apollographql/react-apollo/issues/3090 * Changelog update * Remove unnecessary expect --- CHANGELOG.md | 3 ++ .../apollo-client/src/core/ObservableQuery.ts | 8 ++++ .../src/core/__tests__/ObservableQuery.ts | 45 +++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f59d85e86c..d6f36efa497 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ ### Apollo Client (vNext) +- A new `ObservableQuery.resetQueryStoreErrors()` method is now available that + can be used to clear out `ObservableQuery` query store errors.
+ [@hwillson](https://github.com/hwillson) in [#4941](https://github.com/apollographql/apollo-client/pull/4941) - Documentation updates.
[@michael-watson](https://github.com/michael-watson) in [#4940](https://github.com/apollographql/apollo-client/pull/4940)
[@hwillson](https://github.com/hwillson) in [#4969](https://github.com/apollographql/apollo-client/pull/4969) diff --git a/packages/apollo-client/src/core/ObservableQuery.ts b/packages/apollo-client/src/core/ObservableQuery.ts index 55d70f06a02..6d57e1efa7d 100644 --- a/packages/apollo-client/src/core/ObservableQuery.ts +++ b/packages/apollo-client/src/core/ObservableQuery.ts @@ -280,6 +280,14 @@ export class ObservableQuery< this.isTornDown = false; } + public resetQueryStoreErrors() { + const queryStore = this.queryManager.queryStore.get(this.queryId); + if (queryStore) { + queryStore.networkError = null; + queryStore.graphQLErrors = []; + } + } + /** * Update the variables of this observable query, and fetch the new results. * This method should be preferred over `setVariables` in most use cases. diff --git a/packages/apollo-client/src/core/__tests__/ObservableQuery.ts b/packages/apollo-client/src/core/__tests__/ObservableQuery.ts index 506fcd1e4f2..b6a70dedcd8 100644 --- a/packages/apollo-client/src/core/__tests__/ObservableQuery.ts +++ b/packages/apollo-client/src/core/__tests__/ObservableQuery.ts @@ -4,6 +4,7 @@ import { InMemoryCache, IntrospectionFragmentMatcher, } from 'apollo-cache-inmemory'; +import { GraphQLError } from 'graphql'; import mockQueryManager from '../../__mocks__/mockQueryManager'; import mockWatchQuery from '../../__mocks__/mockWatchQuery'; @@ -1998,4 +1999,48 @@ describe('ObservableQuery', () => { }); }); }); + + describe('resetQueryStoreErrors', () => { + it("should remove any GraphQLError's stored in the query store", (done) => { + const graphQLError = new GraphQLError('oh no!'); + + const observable: ObservableQuery = mockWatchQuery({ + request: { query, variables }, + result: { errors: [graphQLError] }, + }); + + observable.subscribe({ + error() { + const { queryManager } = (observable as any); + const queryStore = queryManager.queryStore.get(observable.queryId); + expect(queryStore.graphQLErrors).toEqual([graphQLError]); + + observable.resetQueryStoreErrors(); + expect(queryStore.graphQLErrors).toEqual([]); + + done(); + } + }); + }); + + it("should remove network error's stored in the query store", (done) => { + const networkError = new Error('oh no!'); + + const observable: ObservableQuery = mockWatchQuery({ + request: { query, variables }, + result: { data: dataOne }, + }); + + observable.subscribe({ + next() { + const { queryManager } = (observable as any); + const queryStore = queryManager.queryStore.get(observable.queryId); + queryStore.networkError = networkError; + observable.resetQueryStoreErrors(); + expect(queryStore.networkError).toBeNull(); + done(); + } + }); + }); + }); });