Skip to content

Commit dae9f87

Browse files
coerceValue: Simplify path printing (#2052)
1 parent 38cee97 commit dae9f87

File tree

3 files changed

+21
-29
lines changed

3 files changed

+21
-29
lines changed

src/execution/__tests__/variables-test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ describe('Execute: Handles inputs', () => {
393393
errors: [
394394
{
395395
message:
396-
'Variable "$input" got invalid value { a: "foo", b: "bar" }; Field value.c of required type String! was not provided.',
396+
'Variable "$input" got invalid value { a: "foo", b: "bar" }; Field of required type String! was not provided at value.c.',
397397
locations: [{ line: 2, column: 16 }],
398398
},
399399
],
@@ -412,12 +412,12 @@ describe('Execute: Handles inputs', () => {
412412
errors: [
413413
{
414414
message:
415-
'Variable "$input" got invalid value { na: { a: "foo" } }; Field value.na.c of required type String! was not provided.',
415+
'Variable "$input" got invalid value { na: { a: "foo" } }; Field of required type String! was not provided at value.na.c.',
416416
locations: [{ line: 2, column: 18 }],
417417
},
418418
{
419419
message:
420-
'Variable "$input" got invalid value { na: { a: "foo" } }; Field value.nb of required type String! was not provided.',
420+
'Variable "$input" got invalid value { na: { a: "foo" } }; Field of required type String! was not provided at value.nb.',
421421
locations: [{ line: 2, column: 18 }],
422422
},
423423
],

src/utilities/__tests__/coerceValue-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ describe('coerceValue', () => {
162162
it('returns error for a missing required field', () => {
163163
const result = coerceValue({ bar: 123 }, TestInputObject);
164164
expectErrors(result).to.deep.equal([
165-
'Field value.foo of required type Int! was not provided.',
165+
'Field of required type Int! was not provided at value.foo.',
166166
]);
167167
});
168168

src/utilities/coerceValue.js

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,12 @@ export function coerceValue(
108108
let errors;
109109
const coercedValue = [];
110110
forEach((value: any), (itemValue, index) => {
111+
const itemPath = { prev: path, key: index };
111112
const coercedItem = coerceValue(
112113
itemValue,
113114
itemType,
114115
blameNode,
115-
atPath(path, index),
116+
itemPath,
116117
);
117118
if (coercedItem.errors) {
118119
errors = add(errors, coercedItem.errors);
@@ -143,6 +144,7 @@ export function coerceValue(
143144

144145
// Ensure every defined field is valid.
145146
for (const field of objectValues(fields)) {
147+
const fieldPath = { prev: path, key: field.name };
146148
const fieldValue = value[field.name];
147149
if (fieldValue === undefined) {
148150
if (field.defaultValue !== undefined) {
@@ -151,9 +153,9 @@ export function coerceValue(
151153
errors = add(
152154
errors,
153155
coercionError(
154-
`Field ${printPath(atPath(path, field.name))} of required ` +
155-
`type ${inspect(field.type)} was not provided`,
156+
`Field of required type ${inspect(field.type)} was not provided`,
156157
blameNode,
158+
fieldPath,
157159
),
158160
);
159161
}
@@ -162,7 +164,7 @@ export function coerceValue(
162164
fieldValue,
163165
field.type,
164166
blameNode,
165-
atPath(path, field.name),
167+
fieldPath,
166168
);
167169
if (coercedField.errors) {
168170
errors = add(errors, coercedField.errors);
@@ -208,17 +210,21 @@ function add(errors, moreErrors) {
208210
return (errors || []).concat(moreErrors);
209211
}
210212

211-
function atPath(prev, key) {
212-
return { prev, key };
213-
}
214-
215213
function coercionError(message, blameNode, path, subMessage, originalError) {
216-
const pathStr = printPath(path);
217214
let fullMessage = message;
218215

219-
if (pathStr) {
220-
fullMessage += ' at ' + pathStr;
216+
// Build a string describing the path into the value where the error was found
217+
if (path) {
218+
const segmentStrings = [];
219+
for (let currentPath = path; currentPath; currentPath = currentPath.prev) {
220+
const { key } = currentPath;
221+
segmentStrings.unshift(
222+
typeof key === 'string' ? '.' + key : '[' + key.toString() + ']',
223+
);
224+
}
225+
fullMessage += ' at value' + segmentStrings.join('');
221226
}
227+
222228
fullMessage += subMessage ? '.' + subMessage : '.';
223229

224230
// Return a GraphQLError instance
@@ -231,17 +237,3 @@ function coercionError(message, blameNode, path, subMessage, originalError) {
231237
originalError,
232238
);
233239
}
234-
235-
// Build a string describing the path into the value where the error was found
236-
function printPath(path) {
237-
let pathStr = '';
238-
let currentPath = path;
239-
while (currentPath) {
240-
pathStr =
241-
(typeof currentPath.key === 'string'
242-
? '.' + currentPath.key
243-
: '[' + String(currentPath.key) + ']') + pathStr;
244-
currentPath = currentPath.prev;
245-
}
246-
return pathStr ? 'value' + pathStr : '';
247-
}

0 commit comments

Comments
 (0)