Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into pr/fix-11988
Browse files Browse the repository at this point in the history
  • Loading branch information
phryneas committed Aug 6, 2024
2 parents 3f30a16 + 8aa627f commit 0547870
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 23 deletions.
5 changes: 0 additions & 5 deletions .changeset/nice-worms-juggle.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/pink-horses-pay.md

This file was deleted.

7 changes: 0 additions & 7 deletions .changeset/short-scissors-speak.md

This file was deleted.

16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# @apollo/client

## 3.11.3

### Patch Changes

- [#11984](https://github.com/apollographql/apollo-client/pull/11984) [`5db1659`](https://github.com/apollographql/apollo-client/commit/5db1659dc07e3de697894fc1c6f00a151d068291) Thanks [@jerelmiller](https://github.com/jerelmiller)! - Fix an issue where multiple fetches with results that returned errors would sometimes set the `data` property with an `errorPolicy` of `none`.

- [#11974](https://github.com/apollographql/apollo-client/pull/11974) [`c95848e`](https://github.com/apollographql/apollo-client/commit/c95848e859fb7ce0b3b9439ac71dff880f991450) Thanks [@jerelmiller](https://github.com/jerelmiller)! - Fix an issue where `fetchMore` would write its result data to the cache when using it with a `no-cache` fetch policy.

- [#11974](https://github.com/apollographql/apollo-client/pull/11974) [`c95848e`](https://github.com/apollographql/apollo-client/commit/c95848e859fb7ce0b3b9439ac71dff880f991450) Thanks [@jerelmiller](https://github.com/jerelmiller)! - Fix an issue where executing `fetchMore` with a `no-cache` fetch policy could sometimes result in multiple network requests.

- [#11974](https://github.com/apollographql/apollo-client/pull/11974) [`c95848e`](https://github.com/apollographql/apollo-client/commit/c95848e859fb7ce0b3b9439ac71dff880f991450) Thanks [@jerelmiller](https://github.com/jerelmiller)! -

#### Potentially disruptive change

When calling `fetchMore` with a query that has a `no-cache` fetch policy, `fetchMore` will now throw if an `updateQuery` function is not provided. This provides a mechanism to merge the results from the `fetchMore` call with the query's previous result.

## 3.11.2

### Patch Changes
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@apollo/client",
"version": "3.11.2",
"version": "3.11.3",
"description": "A fully-featured caching GraphQL client.",
"private": true,
"keywords": [
Expand Down
13 changes: 11 additions & 2 deletions src/core/QueryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1176,11 +1176,12 @@ export class QueryManager<TStore> {
(result) => {
const graphQLErrors = getGraphQLErrorsFromResult(result);
const hasErrors = graphQLErrors.length > 0;
const { errorPolicy } = options;

// If we interrupted this request by calling getResultsFromLink again
// with the same QueryInfo object, we ignore the old results.
if (requestId >= queryInfo.lastRequestId) {
if (hasErrors && options.errorPolicy === "none") {
if (hasErrors && errorPolicy === "none") {
// Throwing here effectively calls observer.error.
throw queryInfo.markError(
new ApolloError({
Expand All @@ -1206,7 +1207,15 @@ export class QueryManager<TStore> {
networkStatus: NetworkStatus.ready,
};

if (hasErrors && options.errorPolicy !== "ignore") {
// In the case we start multiple network requests simulatenously, we
// want to ensure we properly set `data` if we're reporting on an old
// result which will not be caught by the conditional above that ends up
// throwing the markError result.
if (hasErrors && errorPolicy === "none") {
aqr.data = void 0 as TData;
}

if (hasErrors && errorPolicy !== "ignore") {
aqr.errors = graphQLErrors;
aqr.networkStatus = NetworkStatus.error;
}
Expand Down
79 changes: 78 additions & 1 deletion src/react/hooks/__tests__/useQuery.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { Fragment, ReactNode, useEffect, useRef, useState } from "react";
import { DocumentNode, GraphQLError } from "graphql";
import { DocumentNode, GraphQLError, GraphQLFormattedError } from "graphql";
import gql from "graphql-tag";
import { act } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
Expand Down Expand Up @@ -10128,6 +10128,83 @@ describe("useQuery Hook", () => {
link.simulateResult({ result: { data: { hello: "Greetings" } } }, true);
await expect(ProfiledHook).not.toRerender({ timeout: 50 });
expect(requests).toBe(1);
// https://github.com/apollographql/apollo-client/issues/11938
it("does not emit `data` on previous fetch when a 2nd fetch is kicked off and the result returns an error when errorPolicy is none", async () => {
const query = gql`
query {
user {
id
name
}
}
`;

const graphQLError: GraphQLFormattedError = { message: "Cannot get name" };

const mocks = [
{
request: { query },
result: {
data: { user: { __typename: "User", id: "1", name: null } },
errors: [graphQLError],
},
delay: 10,
maxUsageCount: Number.POSITIVE_INFINITY,
},
];

const ProfiledHook = profileHook(() =>
useQuery(query, { notifyOnNetworkStatusChange: true })
);

render(<ProfiledHook />, {
wrapper: ({ children }) => (
<MockedProvider mocks={mocks}>{children}</MockedProvider>
),
});

{
const { loading, data, error } = await ProfiledHook.takeSnapshot();

expect(loading).toBe(true);
expect(data).toBeUndefined();
expect(error).toBeUndefined();
}

{
const { loading, data, error } = await ProfiledHook.takeSnapshot();

expect(loading).toBe(false);
expect(data).toBeUndefined();
expect(error).toEqual(new ApolloError({ graphQLErrors: [graphQLError] }));
}

const { refetch } = ProfiledHook.getCurrentSnapshot();

refetch().catch(() => {});
refetch().catch(() => {});

{
const { loading, networkStatus, data, error } =
await ProfiledHook.takeSnapshot();

expect(loading).toBe(true);
expect(data).toBeUndefined();
expect(networkStatus).toBe(NetworkStatus.refetch);
expect(error).toBeUndefined();
}

{
const { loading, networkStatus, data, error } =
await ProfiledHook.takeSnapshot();

expect(loading).toBe(false);
expect(data).toBeUndefined();
expect(networkStatus).toBe(NetworkStatus.error);
expect(error).toEqual(new ApolloError({ graphQLErrors: [graphQLError] }));
}

await expect(ProfiledHook).not.toRerender({ timeout: 200 });
});
});

Expand Down

0 comments on commit 0547870

Please sign in to comment.