Skip to content

Commit

Permalink
Make protocol errors available in the error link (#12281)
Browse files Browse the repository at this point in the history
Co-authored-by: Lenz Weber-Tronic <lorenz.weber-tronic@apollographql.com>
  • Loading branch information
jerelmiller and phryneas authored Jan 22, 2025
1 parent 7b5c73f commit d638ec3
Show file tree
Hide file tree
Showing 15 changed files with 547 additions and 26 deletions.
4 changes: 2 additions & 2 deletions .api-reports/api-report-core.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,9 @@ export class ApolloLink {
// @public (undocumented)
export interface ApolloPayloadResult<TData = Record<string, any>, TExtensions = Record<string, any>> {
// (undocumented)
errors?: ReadonlyArray<Error | string>;
errors?: ReadonlyArray<GraphQLFormattedError>;
// (undocumented)
payload: SingleExecutionResult | ExecutionPatchResult | null;
payload: SingleExecutionResult<TData, DefaultContext, TExtensions> | ExecutionPatchResult<TData, TExtensions> | null;
}

// @public (undocumented)
Expand Down
8 changes: 4 additions & 4 deletions .api-reports/api-report-link_core.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@ export class ApolloLink {
// @public (undocumented)
export interface ApolloPayloadResult<TData = Record<string, any>, TExtensions = Record<string, any>> {
// (undocumented)
errors?: ReadonlyArray<Error | string>;
errors?: ReadonlyArray<GraphQLFormattedError>;
// Warning: (ae-forgotten-export) The symbol "DefaultContext" needs to be exported by the entry point index.d.ts
//
// (undocumented)
payload: SingleExecutionResult | ExecutionPatchResult | null;
payload: SingleExecutionResult<TData, DefaultContext, TExtensions> | ExecutionPatchResult<TData, TExtensions> | null;
}

// @public (undocumented)
Expand Down Expand Up @@ -106,8 +108,6 @@ export const from: typeof ApolloLink.from;

// @public (undocumented)
export interface GraphQLRequest<TVariables = Record<string, any>> {
// Warning: (ae-forgotten-export) The symbol "DefaultContext" needs to be exported by the entry point index.d.ts
//
// (undocumented)
context?: DefaultContext;
// (undocumented)
Expand Down
8 changes: 5 additions & 3 deletions .api-reports/api-report-link_error.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import type { DocumentNode } from 'graphql';
import type { FormattedExecutionResult } from 'graphql';
import type { GraphQLErrorExtensions } from 'graphql';
import type { GraphQLFormattedError } from 'graphql';
import { Observable } from 'zen-observable-ts';
import type { Observer } from 'zen-observable-ts';
Expand Down Expand Up @@ -80,14 +81,15 @@ export class ErrorLink extends ApolloLink {
export interface ErrorResponse {
// (undocumented)
forward: NextLink;
// (undocumented)
graphQLErrors?: ReadonlyArray<GraphQLFormattedError>;
// Warning: (ae-forgotten-export) The symbol "NetworkError" needs to be exported by the entry point index.d.ts
//
// (undocumented)
networkError?: NetworkError;
// (undocumented)
operation: Operation;
protocolErrors?: ReadonlyArray<{
message: string;
extensions?: GraphQLErrorExtensions[];
}>;
// (undocumented)
response?: FormattedExecutionResult;
}
Expand Down
4 changes: 2 additions & 2 deletions .api-reports/api-report-utilities.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,12 +313,12 @@ class ApolloLink {
// @public (undocumented)
interface ApolloPayloadResult<TData = Record<string, any>, TExtensions = Record<string, any>> {
// (undocumented)
errors?: ReadonlyArray<Error | string>;
errors?: ReadonlyArray<GraphQLFormattedError>;
// Warning: (ae-forgotten-export) The symbol "SingleExecutionResult" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "ExecutionPatchResult" needs to be exported by the entry point index.d.ts
//
// (undocumented)
payload: SingleExecutionResult | ExecutionPatchResult | null;
payload: SingleExecutionResult<TData, DefaultContext, TExtensions> | ExecutionPatchResult<TData, TExtensions> | null;
}

// @public (undocumented)
Expand Down
4 changes: 2 additions & 2 deletions .api-reports/api-report.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,9 @@ export class ApolloLink {
// @public (undocumented)
export interface ApolloPayloadResult<TData = Record<string, any>, TExtensions = Record<string, any>> {
// (undocumented)
errors?: ReadonlyArray<Error | string>;
errors?: ReadonlyArray<GraphQLFormattedError>;
// (undocumented)
payload: SingleExecutionResult | ExecutionPatchResult | null;
payload: SingleExecutionResult<TData, DefaultContext, TExtensions> | ExecutionPatchResult<TData, TExtensions> | null;
}

// Warning: (ae-forgotten-export) The symbol "ApolloProviderProps" needs to be exported by the entry point index.d.ts
Expand Down
13 changes: 13 additions & 0 deletions .changeset/giant-peas-lie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"@apollo/client": patch
---

Make fatal [tranport-level errors](https://www.apollographql.com/docs/graphos/routing/operations/subscriptions/multipart-protocol#message-and-error-format) from multipart subscriptions available to the error link with the `protocolErrors` property.

```js
const errorLink = onError(({ protocolErrors }) => {
if (protocolErrors) {
console.log(protocolErrors);
}
});
```
5 changes: 5 additions & 0 deletions .changeset/mighty-shoes-clap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@apollo/client": patch
---

Fix the array type for the `errors` field on the `ApolloPayloadResult` type. This type was always in the shape of the GraphQL error format, per the [multipart subscriptions protocol](https://www.apollographql.com/docs/graphos/routing/operations/subscriptions/multipart-protocol#message-and-error-format) and never a plain string or a JavaScript error object.
27 changes: 25 additions & 2 deletions docs/source/api/link/apollo-link-error.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,23 @@ Use the `onError` link to perform custom logic when a [GraphQL or network error]
```js
import { onError } from "@apollo/client/link/error";

// Log any GraphQL errors or network error that occurred
const errorLink = onError(({ graphQLErrors, networkError }) => {
// Log any GraphQL errors, protocol errors, or network error that occurred
const errorLink = onError(({ graphQLErrors, networkError, protocolErrors }) => {
if (graphQLErrors)
graphQLErrors.forEach(({ message, locations, path }) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
)
);

if (protocolErrors) {
protocolErrors.forEach(({ message, extensions }) => {
console.log(
`[Protocol error]: Message: ${message}, Extensions: ${JSON.stringify(extensions)}`
);
});
}

if (networkError) console.log(`[Network error]: ${networkError}`);
});
```
Expand Down Expand Up @@ -100,6 +109,20 @@ A network error that occurred while attempting to execute the operation, if any.
</td>
</tr>

<tr>
<td>

###### `protocolErrors`

`ReadonlyArray<{ message: string; extensions?: GraphQLErrorExtensions[]; }>`
</td>
<td>

Fatal transport-level errors from multipart subscriptions. See the [multipart subscription protocol](https://www.apollographql.com/docs/graphos/routing/operations/subscriptions/multipart-protocol#message-and-error-format) for more information.

</td>
</tr>


<tr>
<td>
Expand Down
12 changes: 12 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@
"glob": "8.1.0",
"globals": "15.14.0",
"graphql": "16.9.0",
"graphql-17-alpha2": "npm:graphql@17.0.0-alpha.2",
"graphql-ws": "5.16.0",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
Expand Down
7 changes: 5 additions & 2 deletions src/link/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,13 @@ export interface ApolloPayloadResult<
TData = Record<string, any>,
TExtensions = Record<string, any>,
> {
payload: SingleExecutionResult | ExecutionPatchResult | null;
payload:
| SingleExecutionResult<TData, DefaultContext, TExtensions>
| ExecutionPatchResult<TData, TExtensions>
| null;
// Transport layer errors (as distinct from GraphQL or NetworkErrors),
// these are fatal errors that will include done: true.
errors?: ReadonlyArray<Error | string>;
errors?: ReadonlyArray<GraphQLFormattedError>;
}

export type ExecutionPatchResult<
Expand Down
Loading

0 comments on commit d638ec3

Please sign in to comment.