Skip to content

Commit

Permalink
coerceValue: Simplify path printing (#2052)
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanGoncharov committed Jul 25, 2019
1 parent 38cee97 commit dae9f87
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 29 deletions.
6 changes: 3 additions & 3 deletions src/execution/__tests__/variables-test.js
Expand Up @@ -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 }],
},
],
Expand All @@ -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 }],
},
],
Expand Down
2 changes: 1 addition & 1 deletion src/utilities/__tests__/coerceValue-test.js
Expand Up @@ -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.',
]);
});

Expand Down
42 changes: 17 additions & 25 deletions src/utilities/coerceValue.js
Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand All @@ -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,
),
);
}
Expand All @@ -162,7 +164,7 @@ export function coerceValue(
fieldValue,
field.type,
blameNode,
atPath(path, field.name),
fieldPath,
);
if (coercedField.errors) {
errors = add(errors, coercedField.errors);
Expand Down Expand Up @@ -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
Expand All @@ -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 : '';
}

0 comments on commit dae9f87

Please sign in to comment.