Skip to content

Commit 4ffe3fd

Browse files
committed
introduce completePromiseCatchingErrors
and utilize it within executeStreamField
1 parent 500b458 commit 4ffe3fd

File tree

2 files changed

+51
-35
lines changed

2 files changed

+51
-35
lines changed

src/execution/__tests__/stream-test.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -531,11 +531,6 @@ describe('Execute: stream directive', () => {
531531
},
532532
],
533533
},
534-
],
535-
hasNext: true,
536-
},
537-
{
538-
incremental: [
539534
{
540535
items: [{ name: 'Leia', id: '3' }],
541536
path: ['friendList', 2],

src/execution/execute.ts

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,41 @@ function completeValue(
922922
);
923923
}
924924

925+
async function completePromiseCatchingErrors(
926+
exeContext: ExecutionContext,
927+
returnType: GraphQLOutputType,
928+
fieldNodes: ReadonlyArray<FieldNode>,
929+
info: GraphQLResolveInfo,
930+
path: Path,
931+
result: Promise<unknown>,
932+
asyncPayloadRecord?: AsyncPayloadRecord,
933+
): Promise<unknown> {
934+
try {
935+
const resolved = await result;
936+
let completed = completeValue(
937+
exeContext,
938+
returnType,
939+
fieldNodes,
940+
info,
941+
path,
942+
resolved,
943+
asyncPayloadRecord,
944+
);
945+
if (isPromise(completed)) {
946+
// see: https://github.com/tc39/proposal-faster-promise-adoption
947+
// it is faster to await a promise prior to returning it from an async function
948+
completed = await completed;
949+
}
950+
return completed;
951+
} catch (rawError) {
952+
const errors = asyncPayloadRecord?.errors ?? exeContext.errors;
953+
const error = locatedError(rawError, fieldNodes, pathToArray(path));
954+
const handledError = handleFieldError(error, returnType, errors);
955+
filterSubsequentPayloads(exeContext, path, asyncPayloadRecord);
956+
return handledError;
957+
}
958+
}
959+
925960
/**
926961
* Returns an object containing the `@stream` arguments if a field should be
927962
* streamed based on the experimental flag, stream directive present and
@@ -1897,36 +1932,22 @@ function executeStreamField(
18971932
exeContext,
18981933
});
18991934
if (isPromise(item)) {
1900-
const completedItems = item
1901-
.then((resolved) =>
1902-
completeValue(
1903-
exeContext,
1904-
itemType,
1905-
fieldNodes,
1906-
info,
1907-
itemPath,
1908-
resolved,
1909-
asyncPayloadRecord,
1910-
),
1911-
)
1912-
.then(undefined, (rawError) => {
1913-
const error = locatedError(rawError, fieldNodes, pathToArray(itemPath));
1914-
const handledError = handleFieldError(
1915-
error,
1916-
itemType,
1917-
asyncPayloadRecord.errors,
1918-
);
1919-
filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
1920-
return handledError;
1921-
})
1922-
.then(
1923-
(value) => [value],
1924-
(error) => {
1925-
asyncPayloadRecord.errors.push(error);
1926-
filterSubsequentPayloads(exeContext, path, asyncPayloadRecord);
1927-
return null;
1928-
},
1929-
);
1935+
const completedItems = completePromiseCatchingErrors(
1936+
exeContext,
1937+
itemType,
1938+
fieldNodes,
1939+
info,
1940+
itemPath,
1941+
item,
1942+
asyncPayloadRecord,
1943+
).then(
1944+
(value) => [value],
1945+
(error) => {
1946+
asyncPayloadRecord.errors.push(error);
1947+
filterSubsequentPayloads(exeContext, path, asyncPayloadRecord);
1948+
return null;
1949+
},
1950+
);
19301951

19311952
asyncPayloadRecord.addItems(completedItems);
19321953
return asyncPayloadRecord;

0 commit comments

Comments
 (0)