diff --git a/src/execution/execute.ts b/src/execution/execute.ts index 7d290a8cfaf..aa60825fa20 100644 --- a/src/execution/execute.ts +++ b/src/execution/execute.ts @@ -707,16 +707,14 @@ function executeField( result = resolveFn(source, args, contextValue, info); } catch (rawError) { - const errors = asyncPayloadRecord?.errors ?? exeContext.errors; - const handledError = addError( + handleRawError( rawError, + exeContext, fieldNodes, returnType, path, - errors, + asyncPayloadRecord, ); - filterSubsequentPayloads(exeContext, path, asyncPayloadRecord); - return handledError; } if (isPromise(result)) { @@ -751,32 +749,32 @@ function completePromiseCatchingErrors( result: Promise, asyncPayloadRecord?: AsyncPayloadRecord, ): Promise { - return result - .then((resolved) => - completeValue( - exeContext, - returnType, - fieldNodes, - info, - path, - resolved, - asyncPayloadRecord, - ), - ) - .then(undefined, (rawError) => { + return ( + result + .then((resolved) => + completeValue( + exeContext, + returnType, + fieldNodes, + info, + path, + resolved, + asyncPayloadRecord, + ), + ) // Note: we don't rely on a `catch` method, but we do expect "thenable" // to take a second callback for the error case. - const errors = asyncPayloadRecord?.errors ?? exeContext.errors; - const handledError = addError( - rawError, - fieldNodes, - returnType, - path, - errors, - ); - filterSubsequentPayloads(exeContext, path, asyncPayloadRecord); - return handledError; - }); + .then(undefined, (rawError) => + handleRawError( + rawError, + exeContext, + fieldNodes, + returnType, + path, + asyncPayloadRecord, + ), + ) + ); } function completeValueCatchingErrors( @@ -800,33 +798,29 @@ function completeValueCatchingErrors( asyncPayloadRecord, ); } catch (rawError) { - const errors = asyncPayloadRecord?.errors ?? exeContext.errors; - const handledError = addError( + return handleRawError( rawError, + exeContext, fieldNodes, returnType, path, - errors, + asyncPayloadRecord, ); - filterSubsequentPayloads(exeContext, path, asyncPayloadRecord); - return handledError; } if (isPromise(completedItem)) { // Note: we don't rely on a `catch` method, but we do expect "thenable" // to take a second callback for the error case. - completedItem = completedItem.then(undefined, (rawError) => { - const errors = asyncPayloadRecord?.errors ?? exeContext.errors; - const handledError = addError( + completedItem = completedItem.then(undefined, (rawError) => + handleRawError( rawError, + exeContext, fieldNodes, returnType, path, - errors, - ); - filterSubsequentPayloads(exeContext, path, asyncPayloadRecord); - return handledError; - }); + asyncPayloadRecord, + ), + ); } return completedItem; } @@ -858,6 +852,20 @@ export function buildResolveInfo( }; } +function handleRawError( + rawError: unknown, + exeContext: ExecutionContext, + fieldNodes: ReadonlyArray, + returnType: GraphQLOutputType, + path: Path, + asyncPayloadRecord: AsyncPayloadRecord | undefined, +): null { + const errors = asyncPayloadRecord?.errors ?? exeContext.errors; + addError(rawError, fieldNodes, returnType, path, errors); + filterSubsequentPayloads(exeContext, path, asyncPayloadRecord); + return null; +} + function addError( rawError: unknown, fieldNodes: ReadonlyArray,