Skip to content

Commit 73221d8

Browse files
authored
Remove onError and setOnError from ApolloLink (#12533)
1 parent ae0dcad commit 73221d8

File tree

12 files changed

+20
-160
lines changed

12 files changed

+20
-160
lines changed

Diff for: .api-reports/api-report-link_core.api.md

-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import type { DefaultContext } from '@apollo/client';
88
import type { DocumentNode } from 'graphql';
99
import type { GraphQLFormattedError } from 'graphql';
1010
import type { Observable } from 'rxjs';
11-
import type { Subscriber } from 'rxjs';
1211

1312
// @public (undocumented)
1413
export class ApolloLink {
@@ -28,14 +27,10 @@ export class ApolloLink {
2827
// @internal
2928
readonly left?: ApolloLink;
3029
// (undocumented)
31-
protected onError(error: any, observer?: Subscriber<FetchResult>): false | void;
32-
// (undocumented)
3330
request(operation: Operation, forward?: NextLink): Observable<FetchResult> | null;
3431
// @internal
3532
readonly right?: ApolloLink;
3633
// (undocumented)
37-
setOnError(fn: ApolloLink["onError"]): this;
38-
// (undocumented)
3934
static split(test: (op: Operation) => boolean, left: ApolloLink | RequestHandler, right?: ApolloLink | RequestHandler): ApolloLink;
4035
// (undocumented)
4136
split(test: (op: Operation) => boolean, left: ApolloLink | RequestHandler, right?: ApolloLink | RequestHandler): ApolloLink;

Diff for: .api-reports/api-report.api.md

-5
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import type { Observer } from 'rxjs';
2121
import { resetCaches } from 'graphql-tag';
2222
import type { SelectionSetNode } from 'graphql';
2323
import type { Subscribable } from 'rxjs';
24-
import type { Subscriber } from 'rxjs';
2524
import type { Subscription } from 'rxjs';
2625
import { Trie } from '@wry/trie';
2726
import { TypedDocumentNode } from '@graphql-typed-document-node/core';
@@ -197,14 +196,10 @@ export class ApolloLink {
197196
// @internal
198197
readonly left?: ApolloLink;
199198
// (undocumented)
200-
protected onError(error: any, observer?: Subscriber<FetchResult>): false | void;
201-
// (undocumented)
202199
request(operation: Operation, forward?: NextLink): Observable<FetchResult> | null;
203200
// @internal
204201
readonly right?: ApolloLink;
205202
// (undocumented)
206-
setOnError(fn: ApolloLink["onError"]): this;
207-
// (undocumented)
208203
static split(test: (op: Operation) => boolean, left: ApolloLink | RequestHandler, right?: ApolloLink | RequestHandler): ApolloLink;
209204
// (undocumented)
210205
split(test: (op: Operation) => boolean, left: ApolloLink | RequestHandler, right?: ApolloLink | RequestHandler): ApolloLink;

Diff for: .changeset/giant-apes-thank.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@apollo/client": major
3+
---
4+
5+
Remove the `onError` and `setOnError` methods from `ApolloLink`. `onError` was only used by `MockLink` to rewrite errors if `setOnError` was used.

Diff for: .size-limits.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (CJS)": 42828,
3-
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (production) (CJS)": 38348,
4-
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\"": 32795,
5-
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (production)": 27800
2+
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (CJS)": 42846,
3+
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (production) (CJS)": 38305,
4+
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\"": 32777,
5+
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (production)": 27762
66
}

Diff for: src/__tests__/mutationResults.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,7 @@ describe("mutation results", () => {
164164
delay,
165165
},
166166
...mockedResponses
167-
).setOnError((error) => {
168-
throw error;
169-
}),
167+
),
170168
cache: new InMemoryCache({
171169
dataIdFromObject: (obj: any) => {
172170
if (obj.id && obj.__typename) {

Diff for: src/cache/inmemory/__tests__/policies.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -3654,9 +3654,7 @@ describe("type policies", function () {
36543654
},
36553655
},
36563656
},
3657-
]).setOnError((error) => {
3658-
throw new Error(error);
3659-
});
3657+
]);
36603658

36613659
const client = new ApolloClient({ link, cache });
36623660

@@ -4095,9 +4093,7 @@ describe("type policies", function () {
40954093
},
40964094
},
40974095
},
4098-
]).setOnError((error) => {
4099-
throw new Error(error);
4100-
});
4096+
]);
41014097

41024098
const client = new ApolloClient({ link, cache });
41034099

Diff for: src/link/core/ApolloLink.ts

+1-24
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Observable, Subscriber } from "rxjs";
1+
import type { Observable } from "rxjs";
22
import { EMPTY } from "rxjs";
33

44
import {
@@ -138,29 +138,6 @@ export class ApolloLink {
138138
throw newInvariantError("request is not implemented");
139139
}
140140

141-
protected onError(
142-
error: any,
143-
observer?: Subscriber<FetchResult>
144-
): false | void {
145-
if (observer && observer.error) {
146-
observer.error(error);
147-
// Returning false indicates that observer.error does not need to be
148-
// called again, since it was already called (on the previous line).
149-
// Calling observer.error again would not cause any real problems,
150-
// since only the first call matters, but custom onError functions
151-
// might have other reasons for wanting to prevent the default
152-
// behavior by returning false.
153-
return false;
154-
}
155-
// Throw errors will be passed to observer.error.
156-
throw error;
157-
}
158-
159-
public setOnError(fn: ApolloLink["onError"]): this {
160-
this.onError = fn;
161-
return this;
162-
}
163-
164141
/**
165142
* @internal
166143
* Used to iterate through all links that are concatenations or `split` links.

Diff for: src/react/hooks/__tests__/useQuery.test.tsx

+5-20
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,11 @@ describe("useQuery Hook", () => {
823823
},
824824
{
825825
wrapper: ({ children }) => (
826-
<MockedProvider mocks={mocks} cache={cache}>
826+
<MockedProvider
827+
mocks={mocks}
828+
cache={cache}
829+
mockLinkDefaultOptions={{ delay: 0 }}
830+
>
827831
{children}
828832
</MockedProvider>
829833
),
@@ -2106,8 +2110,6 @@ describe("useQuery Hook", () => {
21062110

21072111
const link = new MockLink(mocks);
21082112
const requestSpy = jest.spyOn(link, "request");
2109-
const onErrorFn = jest.fn();
2110-
link.setOnError(onErrorFn);
21112113
const wrapper = ({ children }: any) => (
21122114
<MockedProvider link={link} cache={cache}>
21132115
{children}
@@ -2162,10 +2164,6 @@ describe("useQuery Hook", () => {
21622164
)
21632165
).rejects.toThrow();
21642166

2165-
await waitFor(() => {
2166-
expect(onErrorFn).toHaveBeenCalledTimes(0);
2167-
});
2168-
21692167
requestSpy.mockRestore();
21702168
});
21712169

@@ -2201,8 +2199,6 @@ describe("useQuery Hook", () => {
22012199

22022200
const link = new MockLink(mocks);
22032201
const requestSpy = jest.spyOn(link, "request");
2204-
const onErrorFn = jest.fn();
2205-
link.setOnError(onErrorFn);
22062202

22072203
const client = new ApolloClient({
22082204
queryDeduplication: false,
@@ -2275,7 +2271,6 @@ describe("useQuery Hook", () => {
22752271
jest.advanceTimersByTime(200);
22762272

22772273
expect(requestSpy).toHaveBeenCalledTimes(2);
2278-
expect(onErrorFn).toHaveBeenCalledTimes(0);
22792274

22802275
jest.useRealTimers();
22812276
});
@@ -2307,8 +2302,6 @@ describe("useQuery Hook", () => {
23072302
const cache = new InMemoryCache();
23082303
const link = new MockLink(mocks);
23092304
const requestSpy = jest.spyOn(link, "request");
2310-
const onErrorFn = jest.fn();
2311-
link.setOnError(onErrorFn);
23122305
const wrapper = ({ children }: any) => (
23132306
<React.StrictMode>
23142307
<MockedProvider link={link} cache={cache}>
@@ -2362,7 +2355,6 @@ describe("useQuery Hook", () => {
23622355
)
23632356
).rejects.toThrow();
23642357
expect(requestSpy).toHaveBeenCalledTimes(requestSpyCallCount);
2365-
expect(onErrorFn).toHaveBeenCalledTimes(0);
23662358

23672359
requestSpy.mockRestore();
23682360
});
@@ -2398,8 +2390,6 @@ describe("useQuery Hook", () => {
23982390

23992391
const link = new MockLink(mocks);
24002392
const requestSpy = jest.spyOn(link, "request");
2401-
const onErrorFn = jest.fn();
2402-
link.setOnError(onErrorFn);
24032393

24042394
const client = new ApolloClient({ link, cache });
24052395

@@ -2464,7 +2454,6 @@ describe("useQuery Hook", () => {
24642454
await expect(takeSnapshot).not.toRerender({ timeout: 50 });
24652455
// TODO rarely seeing 3 here investigate further
24662456
expect(requestSpy).toHaveBeenCalledTimes(2);
2467-
expect(onErrorFn).toHaveBeenCalledTimes(0);
24682457
});
24692458

24702459
it("should start and stop polling in Strict Mode", async () => {
@@ -2495,8 +2484,6 @@ describe("useQuery Hook", () => {
24952484
const cache = new InMemoryCache();
24962485
const link = new MockLink(mocks);
24972486
const requestSpy = jest.spyOn(link, "request");
2498-
const onErrorFn = jest.fn();
2499-
link.setOnError(onErrorFn);
25002487
const wrapper = ({ children }: any) => (
25012488
<React.StrictMode>
25022489
<MockedProvider link={link} cache={cache}>
@@ -2555,7 +2542,6 @@ describe("useQuery Hook", () => {
25552542
getCurrentSnapshot().startPolling(20);
25562543

25572544
expect(requestSpy).toHaveBeenCalledTimes(2);
2558-
expect(onErrorFn).toHaveBeenCalledTimes(0);
25592545

25602546
{
25612547
const result = await takeSnapshot();
@@ -2582,7 +2568,6 @@ describe("useQuery Hook", () => {
25822568
}
25832569

25842570
expect(requestSpy).toHaveBeenCalledTimes(4);
2585-
expect(onErrorFn).toHaveBeenCalledTimes(0);
25862571
requestSpy.mockRestore();
25872572
});
25882573

Diff for: src/testing/core/mocking/mockClient.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { InMemoryCache } from "@apollo/client/cache";
55

66
import { mockSingleLink } from "./mockLink.js";
77

8+
// TODO: Deprecate this function
89
export function createMockClient<TData>(
910
data: TData,
1011
query: DocumentNode,
@@ -14,8 +15,6 @@ export function createMockClient<TData>(
1415
link: mockSingleLink({
1516
request: { query, variables },
1617
result: { data },
17-
}).setOnError((error) => {
18-
throw error;
1918
}),
2019
cache: new InMemoryCache(),
2120
});

Diff for: src/testing/core/mocking/mockLink.ts

+1-8
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,7 @@ export class MockLink extends ApolloLink {
172172
);
173173
}
174174

175-
return throwError(() => {
176-
const error = new Error(message);
177-
178-
// TODO: Remove this once `onError` and `setOnError` is removed.
179-
if (this.onError(error) !== false) {
180-
return error;
181-
}
182-
});
175+
return throwError(() => new Error(message));
183176
}
184177

185178
if (matched.maxUsageCount > 1) {

Diff for: src/testing/react/__tests__/MockedProvider.test.tsx

-55
Original file line numberDiff line numberDiff line change
@@ -998,61 +998,6 @@ describe("General use", () => {
998998
consoleSpy.mockRestore();
999999
});
10001000

1001-
it("should support custom error handling using setOnError", async () => {
1002-
let finished = false;
1003-
function Component({ ...variables }: Variables) {
1004-
useQuery<Data, Variables>(query, { variables });
1005-
return null;
1006-
}
1007-
1008-
const mockLink = new MockLink([], { showWarnings: false });
1009-
mockLink.setOnError((error) => {
1010-
expect(error).toMatchSnapshot();
1011-
finished = true;
1012-
});
1013-
const link = ApolloLink.from([errorLink, mockLink]);
1014-
1015-
render(
1016-
<MockedProvider link={link}>
1017-
<Component {...variables} />
1018-
</MockedProvider>
1019-
);
1020-
1021-
await waitFor(() => {
1022-
expect(finished).toBe(true);
1023-
});
1024-
});
1025-
1026-
it("should pipe exceptions thrown in custom onError functions through the link chain", async () => {
1027-
let finished = false;
1028-
function Component({ ...variables }: Variables) {
1029-
const { loading, error } = useQuery<Data, Variables>(query, {
1030-
variables,
1031-
});
1032-
if (!loading) {
1033-
expect(error).toMatchSnapshot();
1034-
finished = true;
1035-
}
1036-
return null;
1037-
}
1038-
1039-
const mockLink = new MockLink([], { showWarnings: false });
1040-
mockLink.setOnError(() => {
1041-
throw new Error("oh no!");
1042-
});
1043-
const link = ApolloLink.from([errorLink, mockLink]);
1044-
1045-
render(
1046-
<MockedProvider link={link}>
1047-
<Component {...variables} />
1048-
</MockedProvider>
1049-
);
1050-
1051-
await waitFor(() => {
1052-
expect(finished).toBe(true);
1053-
});
1054-
});
1055-
10561001
it("should support loading state testing with delay", async () => {
10571002
jest.useFakeTimers();
10581003

Diff for: src/testing/react/__tests__/__snapshots__/MockedProvider.test.tsx.snap

-28
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,6 @@ Object {
8484
}
8585
`;
8686
87-
exports[`General use should pipe exceptions thrown in custom onError functions through the link chain 1`] = `[Error: oh no!]`;
88-
8987
exports[`General use should return "Mocked response should contain" errors in response 1`] = `
9088
[Error: Mocked response should contain either \`result\`, \`error\` or a \`delay\` of \`Infinity\`:
9189
{
@@ -111,32 +109,6 @@ Request variables: {}
111109
]
112110
`;
113111
114-
exports[`General use should support custom error handling using setOnError 1`] = `
115-
[Error: No more mocked responses for the query:
116-
query GetUser($username: String!) {
117-
user(username: $username) {
118-
id
119-
__typename
120-
}
121-
}
122-
123-
Request variables: {"username":"mock_username"}
124-
]
125-
`;
126-
127-
exports[`General use should support custom error handling using setOnError 2`] = `
128-
[Error: No more mocked responses for the query:
129-
query GetUser($username: String!) {
130-
user(username: $username) {
131-
id
132-
__typename
133-
}
134-
}
135-
136-
Request variables: {"username":"mock_username"}
137-
]
138-
`;
139-
140112
exports[`General use should use the mock if the \`variables\` callback function returns true 1`] = `
141113
Object {
142114
"__typename": "User",

0 commit comments

Comments
 (0)