Skip to content

polish: a few smaller refactors #3756

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 68 additions & 55 deletions src/execution/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,6 @@ function executeField(
path: Path,
asyncPayloadRecord?: AsyncPayloadRecord,
): PromiseOrValue<unknown> {
const errors = asyncPayloadRecord?.errors ?? exeContext.errors;
const fieldName = fieldNodes[0].name.value;
const fieldDef = exeContext.schema.getField(parentType, fieldName);
if (!fieldDef) {
Expand Down Expand Up @@ -749,18 +748,18 @@ function executeField(
// Note: we don't rely on a `catch` method, but we do expect "thenable"
// to take a second callback for the error case.
return completed.then(undefined, (rawError) => {
const error = locatedError(rawError, fieldNodes, pathToArray(path));
const handledError = handleFieldError(error, returnType, errors);
const errors = asyncPayloadRecord?.errors ?? exeContext.errors;
addError(rawError, fieldNodes, returnType, path, errors);
filterSubsequentPayloads(exeContext, path, asyncPayloadRecord);
return handledError;
return null;
});
}
return completed;
} catch (rawError) {
const error = locatedError(rawError, fieldNodes, pathToArray(path));
const handledError = handleFieldError(error, returnType, errors);
const errors = asyncPayloadRecord?.errors ?? exeContext.errors;
addError(rawError, fieldNodes, returnType, path, errors);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this one, especially since addError throws located error.
But since it's not a public API, let's try and merge it.

Future suggestion: If we convert ExecutionContext into class it can have single method called handleFieldError that:

  1. locateError
  2. push error into errors
  3. filterSubsequentPayloads

filterSubsequentPayloads(exeContext, path, asyncPayloadRecord);
return handledError;
return null;
}
}

Expand Down Expand Up @@ -791,11 +790,15 @@ export function buildResolveInfo(
};
}

function handleFieldError(
error: GraphQLError,
function addError(
rawError: unknown,
fieldNodes: ReadonlyArray<FieldNode>,
returnType: GraphQLOutputType,
path: Path,
errors: Array<GraphQLError>,
): null {
): void {
const error = locatedError(rawError, fieldNodes, pathToArray(path));

// If the field type is non-nullable, then it is resolved without any
// protection from errors, however it still properly locates the error.
if (isNonNullType(returnType)) {
Expand All @@ -805,7 +808,6 @@ function handleFieldError(
// Otherwise, error protection is applied, logging the error and resolving
// a null value for this field if one is encountered.
errors.push(error);
return null;
}

/**
Expand Down Expand Up @@ -947,10 +949,9 @@ async function completePromisedValue(
return completed;
} catch (rawError) {
const errors = asyncPayloadRecord?.errors ?? exeContext.errors;
const error = locatedError(rawError, fieldNodes, pathToArray(path));
const handledError = handleFieldError(error, returnType, errors);
addError(rawError, fieldNodes, returnType, path, errors);
filterSubsequentPayloads(exeContext, path, asyncPayloadRecord);
return handledError;
return null;
}
}

Expand Down Expand Up @@ -1052,16 +1053,17 @@ async function completeAsyncIteratorValue(
}

const itemPath = addPath(path, index, undefined);
let iteration;
let iteration: IteratorResult<unknown>;
try {
// eslint-disable-next-line no-await-in-loop
iteration = await iterator.next();
if (iteration.done) {
break;
}
} catch (rawError) {
const error = locatedError(rawError, fieldNodes, pathToArray(itemPath));
completedResults.push(handleFieldError(error, itemType, errors));
addError(rawError, fieldNodes, itemType, itemPath, errors);
completedResults.push(null);
break;
}

if (iteration.done) {
break;
}

Expand Down Expand Up @@ -1224,14 +1226,9 @@ function completeListItemValue(
// to take a second callback for the error case.
completedResults.push(
completedItem.then(undefined, (rawError) => {
const error = locatedError(
rawError,
fieldNodes,
pathToArray(itemPath),
);
const handledError = handleFieldError(error, itemType, errors);
addError(rawError, fieldNodes, itemType, itemPath, errors);
filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
return handledError;
return null;
}),
);

Expand All @@ -1240,10 +1237,9 @@ function completeListItemValue(

completedResults.push(completedItem);
} catch (rawError) {
const error = locatedError(rawError, fieldNodes, pathToArray(itemPath));
const handledError = handleFieldError(error, itemType, errors);
addError(rawError, fieldNodes, itemType, itemPath, errors);
filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
completedResults.push(handledError);
completedResults.push(null);
}

return false;
Expand Down Expand Up @@ -1857,12 +1853,14 @@ function executeStreamField(
asyncPayloadRecord,
);
} catch (rawError) {
const error = locatedError(rawError, fieldNodes, pathToArray(itemPath));
completedItem = handleFieldError(
error,
addError(
rawError,
fieldNodes,
itemType,
itemPath,
asyncPayloadRecord.errors,
);
completedItem = null;
filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
}
} catch (error) {
Expand All @@ -1875,14 +1873,15 @@ function executeStreamField(
if (isPromise(completedItem)) {
const completedItems = completedItem
.then(undefined, (rawError) => {
const error = locatedError(rawError, fieldNodes, pathToArray(itemPath));
const handledError = handleFieldError(
error,
addError(
rawError,
fieldNodes,
itemType,
itemPath,
asyncPayloadRecord.errors,
);
filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
return handledError;
return null;
})
.then(
(value) => [value],
Expand Down Expand Up @@ -1910,20 +1909,28 @@ async function executeStreamIteratorItem(
asyncPayloadRecord: StreamRecord,
itemPath: Path,
): Promise<IteratorResult<unknown>> {
let item;
let iteration: IteratorResult<unknown>;
try {
const { value, done } = await iterator.next();
if (done) {
asyncPayloadRecord.setIsCompletedIterator();
return { done, value: undefined };
}
item = value;
iteration = await iterator.next();
} catch (rawError) {
const error = locatedError(rawError, fieldNodes, pathToArray(itemPath));
const value = handleFieldError(error, itemType, asyncPayloadRecord.errors);
addError(
rawError,
fieldNodes,
itemType,
itemPath,
asyncPayloadRecord.errors,
);
// don't continue if iterator throws
return { done: true, value };
return { done: true, value: null };
}

const { done, value: item } = iteration;

if (done) {
asyncPayloadRecord.setIsCompletedIterator();
return { done, value: undefined };
}

let completedItem;
try {
completedItem = completeValue(
Expand All @@ -1938,22 +1945,28 @@ async function executeStreamIteratorItem(

if (isPromise(completedItem)) {
completedItem = completedItem.then(undefined, (rawError) => {
const error = locatedError(rawError, fieldNodes, pathToArray(itemPath));
const handledError = handleFieldError(
error,
addError(
rawError,
fieldNodes,
itemType,
itemPath,
asyncPayloadRecord.errors,
);
filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
return handledError;
return null;
});
}
return { done: false, value: completedItem };
} catch (rawError) {
const error = locatedError(rawError, fieldNodes, pathToArray(itemPath));
const value = handleFieldError(error, itemType, asyncPayloadRecord.errors);
addError(
rawError,
fieldNodes,
itemType,
itemPath,
asyncPayloadRecord.errors,
);
filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
return { done: false, value };
return { done: false, value: null };
}
}

Expand Down Expand Up @@ -1981,7 +1994,7 @@ async function executeStreamIterator(
exeContext,
});

let iteration;
let iteration: IteratorResult<unknown>;
try {
// eslint-disable-next-line no-await-in-loop
iteration = await executeStreamIteratorItem(
Expand Down