From 1817f06592c017ef871d6381fbdc58e45a2a3ebd Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Thu, 25 Jul 2019 13:01:17 +0300 Subject: [PATCH] coerceValue: Simplify path printing --- src/execution/__tests__/variables-test.js | 6 +-- src/utilities/__tests__/coerceValue-test.js | 2 +- src/utilities/coerceValue.js | 42 +++++++++------------ 3 files changed, 21 insertions(+), 29 deletions(-) diff --git a/src/execution/__tests__/variables-test.js b/src/execution/__tests__/variables-test.js index 33fafeeb5d..336ecfed2b 100644 --- a/src/execution/__tests__/variables-test.js +++ b/src/execution/__tests__/variables-test.js @@ -393,7 +393,7 @@ describe('Execute: Handles inputs', () => { errors: [ { message: - 'Variable "$input" got invalid value { a: "foo", b: "bar" }; Field value.c of required type String! was not provided.', + 'Variable "$input" got invalid value { a: "foo", b: "bar" }; Field of required type String! was not provided at value.c.', locations: [{ line: 2, column: 16 }], }, ], @@ -412,12 +412,12 @@ describe('Execute: Handles inputs', () => { errors: [ { message: - 'Variable "$input" got invalid value { na: { a: "foo" } }; Field value.na.c of required type String! was not provided.', + 'Variable "$input" got invalid value { na: { a: "foo" } }; Field of required type String! was not provided at value.na.c.', locations: [{ line: 2, column: 18 }], }, { message: - 'Variable "$input" got invalid value { na: { a: "foo" } }; Field value.nb of required type String! was not provided.', + 'Variable "$input" got invalid value { na: { a: "foo" } }; Field of required type String! was not provided at value.nb.', locations: [{ line: 2, column: 18 }], }, ], diff --git a/src/utilities/__tests__/coerceValue-test.js b/src/utilities/__tests__/coerceValue-test.js index c7fc8c5531..f23ad0972b 100644 --- a/src/utilities/__tests__/coerceValue-test.js +++ b/src/utilities/__tests__/coerceValue-test.js @@ -162,7 +162,7 @@ describe('coerceValue', () => { it('returns error for a missing required field', () => { const result = coerceValue({ bar: 123 }, TestInputObject); expectErrors(result).to.deep.equal([ - 'Field value.foo of required type Int! was not provided.', + 'Field of required type Int! was not provided at value.foo.', ]); }); diff --git a/src/utilities/coerceValue.js b/src/utilities/coerceValue.js index b7c0e3ae7a..f59c1bb688 100644 --- a/src/utilities/coerceValue.js +++ b/src/utilities/coerceValue.js @@ -108,11 +108,12 @@ export function coerceValue( let errors; const coercedValue = []; forEach((value: any), (itemValue, index) => { + const itemPath = { prev: path, key: index }; const coercedItem = coerceValue( itemValue, itemType, blameNode, - atPath(path, index), + itemPath, ); if (coercedItem.errors) { errors = add(errors, coercedItem.errors); @@ -143,6 +144,7 @@ export function coerceValue( // Ensure every defined field is valid. for (const field of objectValues(fields)) { + const fieldPath = { prev: path, key: field.name }; const fieldValue = value[field.name]; if (fieldValue === undefined) { if (field.defaultValue !== undefined) { @@ -151,9 +153,9 @@ export function coerceValue( errors = add( errors, coercionError( - `Field ${printPath(atPath(path, field.name))} of required ` + - `type ${inspect(field.type)} was not provided`, + `Field of required type ${inspect(field.type)} was not provided`, blameNode, + fieldPath, ), ); } @@ -162,7 +164,7 @@ export function coerceValue( fieldValue, field.type, blameNode, - atPath(path, field.name), + fieldPath, ); if (coercedField.errors) { errors = add(errors, coercedField.errors); @@ -208,17 +210,21 @@ function add(errors, moreErrors) { return (errors || []).concat(moreErrors); } -function atPath(prev, key) { - return { prev, key }; -} - function coercionError(message, blameNode, path, subMessage, originalError) { - const pathStr = printPath(path); let fullMessage = message; - if (pathStr) { - fullMessage += ' at ' + pathStr; + // Build a string describing the path into the value where the error was found + if (path) { + const segmentStrings = []; + for (let currentPath = path; currentPath; currentPath = currentPath.prev) { + const { key } = currentPath; + segmentStrings.unshift( + typeof key === 'string' ? '.' + key : '[' + key.toString() + ']', + ); + } + fullMessage += ' at value' + segmentStrings.join(''); } + fullMessage += subMessage ? '.' + subMessage : '.'; // Return a GraphQLError instance @@ -231,17 +237,3 @@ function coercionError(message, blameNode, path, subMessage, originalError) { originalError, ); } - -// Build a string describing the path into the value where the error was found -function printPath(path) { - let pathStr = ''; - let currentPath = path; - while (currentPath) { - pathStr = - (typeof currentPath.key === 'string' - ? '.' + currentPath.key - : '[' + String(currentPath.key) + ']') + pathStr; - currentPath = currentPath.prev; - } - return pathStr ? 'value' + pathStr : ''; -}