From 5a768372d94c333885ef9e730977d49e25b58932 Mon Sep 17 00:00:00 2001 From: David Glasser Date: Tue, 22 Nov 2022 11:51:26 -0800 Subject: [PATCH] execution: Preserve extensions in parseValue errors Previously, the only fields observed on an error thrown by (for example) parseValue were `message` and `originalError`. Now, the error itself is used as the `originalError`; this may be mildly backwards-incompatible if you added extensions on the error itself which you for some reason wanted to disappear, but that seems unlikely. Addresses an issue raised in https://github.com/apollographql/apollo-server/issues/7178 --- src/execution/__tests__/variables-test.ts | 23 +++++++++++++++++++++++ src/execution/values.ts | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/execution/__tests__/variables-test.ts b/src/execution/__tests__/variables-test.ts index 7c74d8ee92..c3e4341edd 100644 --- a/src/execution/__tests__/variables-test.ts +++ b/src/execution/__tests__/variables-test.ts @@ -5,6 +5,8 @@ import { expectJSON } from '../../__testUtils__/expectJSON.js'; import { inspect } from '../../jsutils/inspect.js'; +import { GraphQLError } from '../../error/GraphQLError.js'; + import { Kind } from '../../language/kinds.js'; import { parse } from '../../language/parser.js'; @@ -29,6 +31,11 @@ import { getVariableValues } from '../values.js'; const TestComplexScalar = new GraphQLScalarType({ name: 'ComplexScalar', parseValue(value) { + if (value === 'ThrowAnError') { + throw new GraphQLError('parseValue throws', { + extensions: { custom: 'extension' }, + }); + } expect(value).to.equal('SerializedValue'); return 'DeserializedValue'; }, @@ -366,6 +373,22 @@ describe('Execute: Handles inputs', () => { }); }); + it('propagates GraphQLError from parseValue', () => { + const params = { input: { c: 'foo', d: 'ThrowAnError' } }; + const result = executeQuery(doc, params); + + expectJSON(result).toDeepEqual({ + errors: [ + { + message: + 'Variable "$input" got invalid value "ThrowAnError" at "input.d"; parseValue throws', + locations: [{ column: 16, line: 2 }], + extensions: { custom: 'extension' }, + }, + ], + }); + }); + it('errors on null for nested non-null', () => { const params = { input: { a: 'foo', b: 'bar', c: null } }; const result = executeQuery(doc, params); diff --git a/src/execution/values.ts b/src/execution/values.ts index bbe3c99c8e..3ebe1be58e 100644 --- a/src/execution/values.ts +++ b/src/execution/values.ts @@ -131,7 +131,7 @@ function coerceVariableValues( onError( new GraphQLError(prefix + '; ' + error.message, { nodes: varDefNode, - originalError: error.originalError, + originalError: error, }), ); },