@@ -1094,66 +1094,86 @@ async function completeAsyncIteratorValue(
10941094 ] ;
10951095 let index = 0 ;
10961096 const streamUsage = getStreamUsage ( exeContext , fieldGroup , path ) ;
1097- // eslint-disable-next-line no-constant-condition
1098- while ( true ) {
1099- if ( streamUsage && index >= streamUsage . initialCount ) {
1100- const streamItemQueue = buildAsyncStreamItemQueue (
1101- index ,
1102- path ,
1103- asyncIterator ,
1104- exeContext ,
1105- streamUsage . fieldGroup ,
1106- info ,
1107- itemType ,
1108- ) ;
1109-
1110- const returnFn = asyncIterator . return ;
1111- let streamRecord : StreamRecord | CancellableStreamRecord ;
1112- if ( returnFn === undefined ) {
1113- streamRecord = {
1114- label : streamUsage . label ,
1115- path,
1116- streamItemQueue,
1117- } ;
1118- } else {
1119- streamRecord = {
1120- label : streamUsage . label ,
1097+ const earlyReturn =
1098+ asyncIterator . return === undefined
1099+ ? undefined
1100+ : asyncIterator . return . bind ( asyncIterator ) ;
1101+ try {
1102+ // eslint-disable-next-line no-constant-condition
1103+ while ( true ) {
1104+ if ( streamUsage && index >= streamUsage . initialCount ) {
1105+ const streamItemQueue = buildAsyncStreamItemQueue (
1106+ index ,
11211107 path ,
1122- streamItemQueue,
1123- earlyReturn : returnFn . bind ( asyncIterator ) ,
1124- } ;
1125- if ( exeContext . cancellableStreams === undefined ) {
1126- exeContext . cancellableStreams = new Set ( ) ;
1108+ asyncIterator ,
1109+ exeContext ,
1110+ streamUsage . fieldGroup ,
1111+ info ,
1112+ itemType ,
1113+ ) ;
1114+
1115+ let streamRecord : StreamRecord | CancellableStreamRecord ;
1116+ if ( earlyReturn === undefined ) {
1117+ streamRecord = {
1118+ label : streamUsage . label ,
1119+ path,
1120+ streamItemQueue,
1121+ } ;
1122+ } else {
1123+ streamRecord = {
1124+ label : streamUsage . label ,
1125+ path,
1126+ earlyReturn,
1127+ streamItemQueue,
1128+ } ;
1129+ if ( exeContext . cancellableStreams === undefined ) {
1130+ exeContext . cancellableStreams = new Set ( ) ;
1131+ }
1132+ exeContext . cancellableStreams . add ( streamRecord ) ;
11271133 }
1128- exeContext . cancellableStreams . add ( streamRecord ) ;
1129- }
11301134
1131- addIncrementalDataRecords ( graphqlWrappedResult , [ streamRecord ] ) ;
1132- break ;
1133- }
1135+ addIncrementalDataRecords ( graphqlWrappedResult , [ streamRecord ] ) ;
1136+ break ;
1137+ }
11341138
1135- const itemPath = addPath ( path , index , undefined ) ;
1136- let iteration ;
1137- try {
1138- // eslint-disable-next-line no-await-in-loop
1139- iteration = await asyncIterator . next ( ) ;
1140- } catch ( rawError ) {
1141- throw locatedError ( rawError , toNodes ( fieldGroup ) , pathToArray ( path ) ) ;
1142- }
1139+ const itemPath = addPath ( path , index , undefined ) ;
1140+ let iteration ;
1141+ try {
1142+ // eslint-disable-next-line no-await-in-loop
1143+ iteration = await asyncIterator . next ( ) ;
1144+ } catch ( rawError ) {
1145+ throw locatedError ( rawError , toNodes ( fieldGroup ) , pathToArray ( path ) ) ;
1146+ }
11431147
1144- // TODO: add test case for stream returning done before initialCount
1145- /* c8 ignore next 3 */
1146- if ( iteration . done ) {
1147- break ;
1148- }
1148+ // TODO: add test case for stream returning done before initialCount
1149+ /* c8 ignore next 3 */
1150+ if ( iteration . done ) {
1151+ break ;
1152+ }
11491153
1150- const item = iteration . value ;
1151- // TODO: add tests for stream backed by asyncIterator that returns a promise
1152- /* c8 ignore start */
1153- if ( isPromise ( item ) ) {
1154- completedResults . push (
1155- completePromisedListItemValue (
1154+ const item = iteration . value ;
1155+ // TODO: add tests for stream backed by asyncIterator that returns a promise
1156+ /* c8 ignore start */
1157+ if ( isPromise ( item ) ) {
1158+ completedResults . push (
1159+ completePromisedListItemValue (
1160+ item ,
1161+ graphqlWrappedResult ,
1162+ exeContext ,
1163+ itemType ,
1164+ fieldGroup ,
1165+ info ,
1166+ itemPath ,
1167+ incrementalContext ,
1168+ deferMap ,
1169+ ) ,
1170+ ) ;
1171+ containsPromise = true ;
1172+ } else if (
1173+ /* c8 ignore stop */
1174+ completeListItemValue (
11561175 item ,
1176+ completedResults ,
11571177 graphqlWrappedResult ,
11581178 exeContext ,
11591179 itemType ,
@@ -1162,30 +1182,23 @@ async function completeAsyncIteratorValue(
11621182 itemPath ,
11631183 incrementalContext ,
11641184 deferMap ,
1165- ) ,
1166- ) ;
1167- containsPromise = true ;
1168- } else if (
1185+ )
1186+ // TODO: add tests for stream backed by asyncIterator that completes to a promise
1187+ /* c8 ignore start */
1188+ ) {
1189+ containsPromise = true ;
1190+ }
11691191 /* c8 ignore stop */
1170- completeListItemValue (
1171- item ,
1172- completedResults ,
1173- graphqlWrappedResult ,
1174- exeContext ,
1175- itemType ,
1176- fieldGroup ,
1177- info ,
1178- itemPath ,
1179- incrementalContext ,
1180- deferMap ,
1181- )
1182- // TODO: add tests for stream backed by asyncIterator that completes to a promise
1183- /* c8 ignore start */
1184- ) {
1185- containsPromise = true ;
1192+ index ++ ;
11861193 }
1187- /* c8 ignore stop */
1188- index ++ ;
1194+ } catch ( error ) {
1195+ if ( earlyReturn !== undefined ) {
1196+ earlyReturn ( ) . catch ( ( ) => {
1197+ /* c8 ignore next 1 */
1198+ // ignore error
1199+ } ) ;
1200+ }
1201+ throw error ;
11891202 }
11901203
11911204 return containsPromise
0 commit comments