Skip to content

Commit

Permalink
fix(server): onError should return GraphQLFormattedError (#599)
Browse files Browse the repository at this point in the history
Co-authored-by: Denis Badurina <[email protected]>
Co-authored-by: enisdenjo <[email protected]>
  • Loading branch information
3 people committed Jan 14, 2025
1 parent d000e6c commit f2e60eb
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/long-glasses-drive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'graphql-ws': major
---

`ErrorMessage` uses and `onError` returns `GraphQLFormattedError` (instead of `GraphQLError`)
8 changes: 4 additions & 4 deletions src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
*
*/

import { GraphQLError } from 'graphql';
import { areGraphQLErrors, extendedTypeof, isObject } from './utils';
import { GraphQLError, GraphQLFormattedError } from 'graphql';
import { areGraphQLFormattedErrors, extendedTypeof, isObject } from './utils';

/**
* The WebSocket sub-protocol used for the [GraphQL over WebSocket Protocol](https://github.com/graphql/graphql-over-http/blob/main/rfcs/GraphQLOverWebSocket.md).
Expand Down Expand Up @@ -169,7 +169,7 @@ export interface NextMessage {
export interface ErrorMessage {
readonly id: ID;
readonly type: MessageType.Error;
readonly payload: readonly GraphQLError[];
readonly payload: readonly GraphQLFormattedError[];
}

/** @category Common */
Expand Down Expand Up @@ -354,7 +354,7 @@ export function validateMessage(val: unknown): Message {
);
}

if (!areGraphQLErrors(val.payload)) {
if (!areGraphQLFormattedErrors(val.payload)) {
throw new Error(
`"${
val.type
Expand Down
7 changes: 4 additions & 3 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
getOperationAST,
GraphQLError,
execute as graphqlExecute,
GraphQLFormattedError,
GraphQLSchema,
subscribe as graphqlSubscribe,
validate as graphqlValidate,
Expand Down Expand Up @@ -360,8 +361,8 @@ export interface ServerOptions<
message: ErrorMessage,
errors: readonly GraphQLError[],
) =>
| Promise<readonly GraphQLError[] | void>
| readonly GraphQLError[]
| Promise<readonly GraphQLFormattedError[] | void>
| readonly GraphQLFormattedError[]
| void);
/**
* Executed after an operation has emitted a result right before
Expand Down Expand Up @@ -718,7 +719,7 @@ export function makeServer<
let errorMessage: ErrorMessage = {
id,
type: MessageType.Error,
payload: errors,
payload: errors.map((e) => e.toJSON()),
};
const maybeErrors = await onError?.(ctx, errorMessage, errors);
if (maybeErrors)
Expand Down
17 changes: 15 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* utils
*
*/
import { GraphQLError } from 'graphql';
import { GraphQLError, GraphQLFormattedError } from 'graphql';

/** @private */
export function extendedTypeof(
Expand Down Expand Up @@ -55,7 +55,9 @@ export function isAsyncGenerator<T = unknown>(
}

/** @private */
export function areGraphQLErrors(obj: unknown): obj is readonly GraphQLError[] {
export function areGraphQLFormattedErrors(
obj: unknown,
): obj is readonly GraphQLFormattedError[] {
return (
Array.isArray(obj) &&
// must be at least one error
Expand All @@ -65,6 +67,17 @@ export function areGraphQLErrors(obj: unknown): obj is readonly GraphQLError[] {
);
}

/** @private */
export function areGraphQLErrors(obj: unknown): obj is readonly GraphQLError[] {
return (
Array.isArray(obj) &&
// must be at least one error
obj.length > 0 &&
// error has at least a message
obj.every((ob) => ob instanceof GraphQLError)
);
}

/**
* Limits the WebSocket close event reason to not exceed a length of one frame.
* Reference: https://datatracker.ietf.org/doc/html/rfc6455#section-5.2.
Expand Down
5 changes: 4 additions & 1 deletion tests/server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1077,7 +1077,10 @@ describe.concurrent('Subscribe', () => {
}) => {
const { url } = await startTServer({
onError: (_ctx, _message) => {
return [new GraphQLError('Itsa me!'), new GraphQLError('Anda me!')];
return [
new GraphQLError('Itsa me!').toJSON(),
new GraphQLError('Anda me!').toJSON(),
];
},
});

Expand Down

0 comments on commit f2e60eb

Please sign in to comment.