From a91fdc600f2012a60e44356c373e51c5dd20ba81 Mon Sep 17 00:00:00 2001 From: Laurin Quast Date: Thu, 20 Jan 2022 10:03:00 +0100 Subject: [PATCH] feat: allow providing an object to the GraphQLError constructor (#3454) --- src/error/GraphQLError.ts | 44 +++++++++++++++++++++++- src/error/__tests__/GraphQLError-test.ts | 18 ++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/error/GraphQLError.ts b/src/error/GraphQLError.ts index 6d6677fa16..c859f59e46 100644 --- a/src/error/GraphQLError.ts +++ b/src/error/GraphQLError.ts @@ -20,6 +20,41 @@ export interface GraphQLErrorExtensions { [attributeName: string]: unknown; } +export interface GraphQLErrorArgs { + nodes?: ReadonlyArray | ASTNode | null; + source?: Maybe; + positions?: Maybe>; + path?: Maybe>; + originalError?: Maybe; + extensions?: Maybe; +} + +type BackwardsCompatibleArgs = + | [args?: GraphQLErrorArgs] + | [ + nodes?: GraphQLErrorArgs['nodes'], + source?: GraphQLErrorArgs['source'], + positions?: GraphQLErrorArgs['positions'], + path?: GraphQLErrorArgs['path'], + originalError?: GraphQLErrorArgs['originalError'], + extensions?: GraphQLErrorArgs['extensions'], + ]; + +function toNormalizedArgs(args: BackwardsCompatibleArgs): GraphQLErrorArgs { + const firstArg = args[0]; + if (firstArg == null || 'kind' in firstArg || 'length' in firstArg) { + return { + nodes: firstArg, + source: args[1], + positions: args[2], + path: args[3], + originalError: args[4], + extensions: args[5], + }; + } + return firstArg; +} + /** * A GraphQLError describes an Error found during the parse, validate, or * execute phases of performing a GraphQL operation. In addition to a message @@ -76,6 +111,9 @@ export class GraphQLError extends Error { */ readonly extensions: GraphQLErrorExtensions; + /** + * @deprecated Please use the `GraphQLErrorArgs` constructor overload instead. + */ constructor( message: string, nodes?: ReadonlyArray | ASTNode | null, @@ -84,7 +122,11 @@ export class GraphQLError extends Error { path?: Maybe>, originalError?: Maybe, extensions?: Maybe, - ) { + ); + constructor(message: string, args?: GraphQLErrorArgs); + constructor(message: string, ...rawArgs: BackwardsCompatibleArgs) { + const { nodes, source, positions, path, originalError, extensions } = + toNormalizedArgs(rawArgs); super(message); this.name = 'GraphQLError'; diff --git a/src/error/__tests__/GraphQLError-test.ts b/src/error/__tests__/GraphQLError-test.ts index 21e1ab1f5b..60f35e9b6c 100644 --- a/src/error/__tests__/GraphQLError-test.ts +++ b/src/error/__tests__/GraphQLError-test.ts @@ -353,4 +353,22 @@ describe('toJSON', () => { extensions: { foo: 'bar' }, }); }); + + it('can be created with the alternative object argument', () => { + const error = new GraphQLError('msg', { + nodes: [operationNode], + source, + positions: [6], + path: ['path', 2, 'a'], + originalError: new Error('I like turtles'), + extensions: { hee: 'I like turtles' }, + }); + + expect(error.toJSON()).to.deep.equal({ + message: 'msg', + locations: [{ column: 5, line: 2 }], + path: ['path', 2, 'a'], + extensions: { hee: 'I like turtles' }, + }); + }); });