Skip to content

Commit 6afff60

Browse files
authored
Unify subscription error behavior and update emitted type (#12476)
1 parent 3de63eb commit 6afff60

23 files changed

+731
-341
lines changed

.api-reports/api-report-core.api.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ export class ApolloClient implements DataProxy_2 {
173173
setLocalStateFragmentMatcher(fragmentMatcher: FragmentMatcher): void;
174174
setResolvers(resolvers: Resolvers | Resolvers[]): void;
175175
stop(): void;
176-
subscribe<TData = unknown, TVariables extends OperationVariables = OperationVariables>(options: SubscriptionOptions<TVariables, TData>): Observable<FetchResult_2<MaybeMasked_2<TData>>>;
176+
subscribe<TData = unknown, TVariables extends OperationVariables = OperationVariables>(options: SubscriptionOptions<TVariables, TData>): Observable<SubscribeResult<MaybeMasked_2<TData>>>;
177177
// (undocumented)
178178
readonly typeDefs: ApolloClientOptions["typeDefs"];
179179
// (undocumented)
@@ -1823,7 +1823,7 @@ class QueryManager {
18231823
// (undocumented)
18241824
readonly ssrMode: boolean;
18251825
// (undocumented)
1826-
startGraphQLSubscription<TData = unknown>(options: SubscriptionOptions): Observable<FetchResult_2<TData>>;
1826+
startGraphQLSubscription<TData = unknown>(options: SubscriptionOptions): Observable<SubscribeResult<TData>>;
18271827
stop(): void;
18281828
// (undocumented)
18291829
stopQuery(queryId: string): void;
@@ -2109,6 +2109,13 @@ class Stump extends Layer {
21092109
removeLayer(): this;
21102110
}
21112111

2112+
// @public (undocumented)
2113+
export interface SubscribeResult<TData = unknown> {
2114+
data: TData | undefined;
2115+
error?: ErrorLike;
2116+
extensions?: Record<string, unknown>;
2117+
}
2118+
21122119
// @public (undocumented)
21132120
export interface SubscribeToMoreFunction<TData, TVariables extends OperationVariables = OperationVariables> {
21142121
// (undocumented)
@@ -2328,8 +2335,8 @@ interface WriteContext extends ReadMergeModifyContext {
23282335
// src/cache/inmemory/types.ts:133:3 - (ae-forgotten-export) The symbol "KeyFieldsFunction" needs to be exported by the entry point index.d.ts
23292336
// src/core/ObservableQuery.ts:128:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts
23302337
// src/core/ObservableQuery.ts:129:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts
2331-
// src/core/QueryManager.ts:185:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts
2332-
// src/core/QueryManager.ts:456:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts
2338+
// src/core/QueryManager.ts:187:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts
2339+
// src/core/QueryManager.ts:458:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts
23332340
// src/link/http/selectHttpOptionsAndBody.ts:128:1 - (ae-forgotten-export) The symbol "HttpQueryOptions" needs to be exported by the entry point index.d.ts
23342341

23352342
// (No @packageDocumentation comment for this package)

.api-reports/api-report-react.api.md

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ class ApolloClient_2 implements DataProxy {
146146
setResolvers(resolvers: Resolvers | Resolvers[]): void;
147147
stop(): void;
148148
// Warning: (ae-forgotten-export) The symbol "SubscriptionOptions" needs to be exported by the entry point index.d.ts
149-
subscribe<TData = unknown, TVariables extends OperationVariables_2 = OperationVariables_2>(options: SubscriptionOptions<TVariables, TData>): Observable<FetchResult<MaybeMasked<TData>>>;
149+
// Warning: (ae-forgotten-export) The symbol "SubscribeResult" needs to be exported by the entry point index.d.ts
150+
subscribe<TData = unknown, TVariables extends OperationVariables_2 = OperationVariables_2>(options: SubscriptionOptions<TVariables, TData>): Observable<SubscribeResult<MaybeMasked<TData>>>;
150151
// Warning: (ae-forgotten-export) The symbol "ApolloClientOptions" needs to be exported by the entry point index.d.ts
151152
//
152153
// (undocumented)
@@ -870,7 +871,7 @@ class QueryManager {
870871
// (undocumented)
871872
readonly ssrMode: boolean;
872873
// (undocumented)
873-
startGraphQLSubscription<TData = unknown>(options: SubscriptionOptions): Observable<FetchResult<TData>>;
874+
startGraphQLSubscription<TData = unknown>(options: SubscriptionOptions): Observable<SubscribeResult<TData>>;
874875
stop(): void;
875876
// (undocumented)
876877
stopQuery(queryId: string): void;
@@ -995,6 +996,13 @@ export type SkipToken = typeof skipToken;
995996
// @public (undocumented)
996997
export const skipToken: unique symbol;
997998

999+
// @public (undocumented)
1000+
interface SubscribeResult<TData = unknown> {
1001+
data: TData | undefined;
1002+
error?: ErrorLike;
1003+
extensions?: Record<string, unknown>;
1004+
}
1005+
9981006
// @public (undocumented)
9991007
interface SubscribeToMoreOptions<TData = unknown, TSubscriptionVariables extends OperationVariables_2 = OperationVariables_2, TSubscriptionData = TData, TVariables extends OperationVariables_2 = TSubscriptionVariables> {
10001008
// (undocumented)
@@ -1464,13 +1472,7 @@ export namespace useReadQuery {
14641472
export type UseReadQueryResult<TData = unknown> = useReadQuery_2.Result<TData>;
14651473

14661474
// @public
1467-
export function useSubscription<TData = unknown, TVariables extends OperationVariables = OperationVariables>(subscription: DocumentNode | TypedDocumentNode_2<TData, TVariables>, options?: useSubscription.Options<NoInfer_2<TData>, NoInfer_2<TVariables>>): {
1468-
restart: () => void;
1469-
loading: boolean;
1470-
data?: TData | undefined;
1471-
error?: ErrorLike_2;
1472-
variables?: TVariables | undefined;
1473-
};
1475+
export function useSubscription<TData = unknown, TVariables extends OperationVariables = OperationVariables>(subscription: DocumentNode | TypedDocumentNode_2<TData, TVariables>, options?: useSubscription.Options<NoInfer_2<TData>, NoInfer_2<TVariables>>): useSubscription.Result<TData, TVariables>;
14741476

14751477
// @public (undocumented)
14761478
export namespace useSubscription {
@@ -1479,14 +1481,16 @@ export namespace useSubscription {
14791481
// (undocumented)
14801482
client: ApolloClient;
14811483
// (undocumented)
1482-
data: Result<TData>;
1484+
data: OnDataResult<TData>;
14831485
}
14841486
// (undocumented)
1487+
export type OnDataResult<TData = unknown> = Omit<Result<TData>, "restart">;
1488+
// (undocumented)
14851489
export interface OnSubscriptionDataOptions<TData = unknown> {
14861490
// (undocumented)
14871491
client: ApolloClient;
14881492
// (undocumented)
1489-
subscriptionData: Result<TData>;
1493+
subscriptionData: OnDataResult<TData>;
14901494
}
14911495
// (undocumented)
14921496
export interface Options<TData = unknown, TVariables extends OperationVariables = OperationVariables> {
@@ -1512,6 +1516,8 @@ export namespace useSubscription {
15121516
data?: MaybeMasked<TData>;
15131517
error?: ErrorLike_2;
15141518
loading: boolean;
1519+
// (undocumented)
1520+
restart: () => void;
15151521
// @internal (undocumented)
15161522
variables?: TVariables;
15171523
}
@@ -1655,8 +1661,8 @@ interface WatchQueryOptions_2<TVariables extends OperationVariables_2 = Operatio
16551661
// src/core/LocalState.ts:71:3 - (ae-forgotten-export) The symbol "ApolloClient_2" needs to be exported by the entry point index.d.ts
16561662
// src/core/ObservableQuery.ts:128:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts
16571663
// src/core/ObservableQuery.ts:129:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts
1658-
// src/core/QueryManager.ts:185:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts
1659-
// src/core/QueryManager.ts:456:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts
1664+
// src/core/QueryManager.ts:187:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts
1665+
// src/core/QueryManager.ts:458:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts
16601666
// src/core/types.ts:204:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts
16611667
// src/core/types.ts:233:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts
16621668
// src/core/watchQueryOptions.ts:195:3 - (ae-forgotten-export) The symbol "UpdateQueryOptions" needs to be exported by the entry point index.d.ts

.api-reports/api-report-react_hooks.api.md

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ class ApolloClient_2 implements DataProxy {
130130
setResolvers(resolvers: Resolvers | Resolvers[]): void;
131131
stop(): void;
132132
// Warning: (ae-forgotten-export) The symbol "SubscriptionOptions" needs to be exported by the entry point index.d.ts
133-
subscribe<TData = unknown, TVariables extends OperationVariables_2 = OperationVariables_2>(options: SubscriptionOptions<TVariables, TData>): Observable<FetchResult<MaybeMasked<TData>>>;
133+
// Warning: (ae-forgotten-export) The symbol "SubscribeResult" needs to be exported by the entry point index.d.ts
134+
subscribe<TData = unknown, TVariables extends OperationVariables_2 = OperationVariables_2>(options: SubscriptionOptions<TVariables, TData>): Observable<SubscribeResult<MaybeMasked<TData>>>;
134135
// Warning: (ae-forgotten-export) The symbol "ApolloClientOptions" needs to be exported by the entry point index.d.ts
135136
//
136137
// (undocumented)
@@ -686,7 +687,7 @@ class QueryManager {
686687
// (undocumented)
687688
readonly ssrMode: boolean;
688689
// (undocumented)
689-
startGraphQLSubscription<TData = unknown>(options: SubscriptionOptions): Observable<FetchResult<TData>>;
690+
startGraphQLSubscription<TData = unknown>(options: SubscriptionOptions): Observable<SubscribeResult<TData>>;
690691
stop(): void;
691692
// (undocumented)
692693
stopQuery(queryId: string): void;
@@ -796,6 +797,13 @@ export type SkipToken = typeof skipToken;
796797
// @public (undocumented)
797798
export const skipToken: unique symbol;
798799

800+
// @public (undocumented)
801+
interface SubscribeResult<TData = unknown> {
802+
data: TData | undefined;
803+
error?: ErrorLike;
804+
extensions?: Record<string, unknown>;
805+
}
806+
799807
// @public (undocumented)
800808
interface SubscribeToMoreOptions<TData = unknown, TSubscriptionVariables extends OperationVariables_2 = OperationVariables_2, TSubscriptionData = TData, TVariables extends OperationVariables_2 = TSubscriptionVariables> {
801809
// (undocumented)
@@ -1235,13 +1243,7 @@ export namespace useReadQuery {
12351243
}
12361244

12371245
// @public
1238-
export function useSubscription<TData = unknown, TVariables extends OperationVariables = OperationVariables>(subscription: DocumentNode | TypedDocumentNode<TData, TVariables>, options?: useSubscription.Options<NoInfer_2<TData>, NoInfer_2<TVariables>>): {
1239-
restart: () => void;
1240-
loading: boolean;
1241-
data?: TData | undefined;
1242-
error?: ErrorLike_2;
1243-
variables?: TVariables | undefined;
1244-
};
1246+
export function useSubscription<TData = unknown, TVariables extends OperationVariables = OperationVariables>(subscription: DocumentNode | TypedDocumentNode<TData, TVariables>, options?: useSubscription.Options<NoInfer_2<TData>, NoInfer_2<TVariables>>): useSubscription.Result<TData, TVariables>;
12451247

12461248
// @public (undocumented)
12471249
export namespace useSubscription {
@@ -1250,14 +1252,16 @@ export namespace useSubscription {
12501252
// (undocumented)
12511253
client: ApolloClient;
12521254
// (undocumented)
1253-
data: Result<TData>;
1255+
data: OnDataResult<TData>;
12541256
}
12551257
// (undocumented)
1258+
export type OnDataResult<TData = unknown> = Omit<Result<TData>, "restart">;
1259+
// (undocumented)
12561260
export interface OnSubscriptionDataOptions<TData = unknown> {
12571261
// (undocumented)
12581262
client: ApolloClient;
12591263
// (undocumented)
1260-
subscriptionData: Result<TData>;
1264+
subscriptionData: OnDataResult<TData>;
12611265
}
12621266
// (undocumented)
12631267
export interface Options<TData = unknown, TVariables extends OperationVariables = OperationVariables> {
@@ -1283,6 +1287,8 @@ export namespace useSubscription {
12831287
data?: MaybeMasked<TData>;
12841288
error?: ErrorLike_2;
12851289
loading: boolean;
1290+
// (undocumented)
1291+
restart: () => void;
12861292
// @internal (undocumented)
12871293
variables?: TVariables;
12881294
}
@@ -1417,8 +1423,8 @@ interface WatchQueryOptions_2<TVariables extends OperationVariables_2 = Operatio
14171423
// src/core/LocalState.ts:71:3 - (ae-forgotten-export) The symbol "ApolloClient_2" needs to be exported by the entry point index.d.ts
14181424
// src/core/ObservableQuery.ts:128:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts
14191425
// src/core/ObservableQuery.ts:129:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts
1420-
// src/core/QueryManager.ts:185:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts
1421-
// src/core/QueryManager.ts:456:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts
1426+
// src/core/QueryManager.ts:187:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts
1427+
// src/core/QueryManager.ts:458:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts
14221428
// src/core/types.ts:204:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts
14231429
// src/core/types.ts:233:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts
14241430
// src/core/watchQueryOptions.ts:195:3 - (ae-forgotten-export) The symbol "UpdateQueryOptions" needs to be exported by the entry point index.d.ts

.api-reports/api-report.api.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export class ApolloClient implements DataProxy {
137137
setLocalStateFragmentMatcher(fragmentMatcher: FragmentMatcher): void;
138138
setResolvers(resolvers: Resolvers | Resolvers[]): void;
139139
stop(): void;
140-
subscribe<TData = unknown, TVariables extends OperationVariables = OperationVariables>(options: SubscriptionOptions<TVariables, TData>): Observable<FetchResult<MaybeMasked<TData>>>;
140+
subscribe<TData = unknown, TVariables extends OperationVariables = OperationVariables>(options: SubscriptionOptions<TVariables, TData>): Observable<SubscribeResult<MaybeMasked<TData>>>;
141141
// (undocumented)
142142
readonly typeDefs: ApolloClientOptions["typeDefs"];
143143
// (undocumented)
@@ -1939,7 +1939,7 @@ class QueryManager {
19391939
// (undocumented)
19401940
readonly ssrMode: boolean;
19411941
// (undocumented)
1942-
startGraphQLSubscription<TData = unknown>(options: SubscriptionOptions): Observable<FetchResult<TData>>;
1942+
startGraphQLSubscription<TData = unknown>(options: SubscriptionOptions): Observable<SubscribeResult<TData>>;
19431943
stop(): void;
19441944
// (undocumented)
19451945
stopQuery(queryId: string): void;
@@ -2233,6 +2233,13 @@ class Stump extends Layer {
22332233
removeLayer(): this;
22342234
}
22352235

2236+
// @public (undocumented)
2237+
export interface SubscribeResult<TData = unknown> {
2238+
data: TData | undefined;
2239+
error?: ErrorLike;
2240+
extensions?: Record<string, unknown>;
2241+
}
2242+
22362243
// @public (undocumented)
22372244
export interface SubscribeToMoreFunction<TData, TVariables extends OperationVariables = OperationVariables> {
22382245
// (undocumented)
@@ -2470,8 +2477,8 @@ interface WriteContext extends ReadMergeModifyContext {
24702477
// src/cache/inmemory/types.ts:133:3 - (ae-forgotten-export) The symbol "KeyFieldsFunction" needs to be exported by the entry point index.d.ts
24712478
// src/core/ObservableQuery.ts:128:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts
24722479
// src/core/ObservableQuery.ts:129:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts
2473-
// src/core/QueryManager.ts:185:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts
2474-
// src/core/QueryManager.ts:456:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts
2480+
// src/core/QueryManager.ts:187:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts
2481+
// src/core/QueryManager.ts:458:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts
24752482
// src/link/http/selectHttpOptionsAndBody.ts:128:1 - (ae-forgotten-export) The symbol "HttpQueryOptions" needs to be exported by the entry point index.d.ts
24762483

24772484
// (No @packageDocumentation comment for this package)

.changeset/forty-shrimps-fry.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@apollo/client": major
3+
---
4+
5+
Subscriptions now emit a `SubscribeResult` instead of a `FetchResult`. As a result, the `errors` field has been removed in favor of `error`.

.changeset/real-teachers-peel.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@apollo/client": major
3+
---
4+
5+
Unify error behavior on subscriptions for GraphQL errors and network errors by ensuring network errors are subject to the `errorPolicy`. Network errors that terminate the connection will now be emitted on the `error` property passed to the `next` callback followed by a call to the `complete` callback.

.changeset/tricky-tables-shave.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@apollo/client": major
3+
---
4+
5+
GraphQL errors or network errors emitted while using an `errorPolicy` of `ignore` in subscriptions will no longer emit a result if there is no `data` emitted along with the error.

.changeset/warm-ties-sit.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@apollo/client": major
3+
---
4+
5+
Subscriptions no longer emit errors in the `error` callback and instead provide errors on the `error` property on the result passed to the `next` callback. As a result, errors will no longer automatically terminate the connection allowing additional results to be emitted when the connection stays open.
6+
7+
When an error terminates the downstream connection, a `next` event will be emitted with an `error` property followed by a `complete` event instead.

.size-limits.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (CJS)": 42184,
3-
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (production) (CJS)": 37665,
4-
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\"": 32637,
5-
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (production)": 27537
2+
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (CJS)": 42313,
3+
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (production) (CJS)": 37697,
4+
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\"": 32739,
5+
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (production)": 27589
66
}

src/__tests__/client.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6253,7 +6253,7 @@ describe("custom document transforms", () => {
62536253
});
62546254

62556255
describe("unconventional errors", () => {
6256-
test("wraps error mesage in Error type when erroring with a string", async () => {
6256+
test("wraps error message in Error type when erroring with a string", async () => {
62576257
const query = gql`
62586258
query {
62596259
hello
@@ -6277,7 +6277,7 @@ describe("unconventional errors", () => {
62776277

62786278
const stream = new ObservableStream(client.watchQuery({ query }));
62796279

6280-
await expect(stream).toEmitApolloQueryResult({
6280+
await expect(stream).toEmitStrictTyped({
62816281
data: undefined,
62826282
error: expectedError,
62836283
loading: false,
@@ -6304,7 +6304,10 @@ describe("unconventional errors", () => {
63046304
});
63056305
const subscriptionStream = new ObservableStream(subscription);
63066306

6307-
await expect(subscriptionStream).toEmitError(expectedError);
6307+
await expect(subscriptionStream).toEmitStrictTyped({
6308+
data: undefined,
6309+
error: expectedError,
6310+
});
63086311
});
63096312

63106313
test("wraps unconventional types in UnconventionalError", async () => {
@@ -6332,7 +6335,7 @@ describe("unconventional errors", () => {
63326335

63336336
const stream = new ObservableStream(client.watchQuery({ query }));
63346337

6335-
await expect(stream).toEmitApolloQueryResult({
6338+
await expect(stream).toEmitStrictTyped({
63366339
data: undefined,
63376340
error: expectedError,
63386341
loading: false,
@@ -6359,7 +6362,10 @@ describe("unconventional errors", () => {
63596362
});
63606363
const subscriptionStream = new ObservableStream(subscription);
63616364

6362-
await expect(subscriptionStream).toEmitError(expectedError);
6365+
await expect(subscriptionStream).toEmitStrictTyped({
6366+
data: undefined,
6367+
error: expectedError,
6368+
});
63636369
}
63646370
});
63656371
});

0 commit comments

Comments
 (0)