@@ -165,11 +165,13 @@ export interface ExecutionContext {
165165 validatedExecutionArgs : ValidatedExecutionArgs ;
166166 errors : Array < GraphQLError > | undefined ;
167167 promiseCanceller : PromiseCanceller | undefined ;
168+ completed : boolean ;
168169 cancellableStreams : Set < CancellableStreamRecord > | undefined ;
169170}
170171
171172interface IncrementalContext {
172173 errors : Array < GraphQLError > | undefined ;
174+ completed : boolean ;
173175 deferUsageSet ?: DeferUsageSet | undefined ;
174176}
175177
@@ -319,6 +321,7 @@ export function experimentalExecuteQueryOrMutationOrSubscriptionEvent(
319321 promiseCanceller : abortSignal
320322 ? new PromiseCanceller ( abortSignal )
321323 : undefined ,
324+ completed : false ,
322325 cancellableStreams : undefined ,
323326 } ;
324327 try {
@@ -369,8 +372,12 @@ export function experimentalExecuteQueryOrMutationOrSubscriptionEvent(
369372
370373 if ( isPromise ( graphqlWrappedResult ) ) {
371374 return graphqlWrappedResult . then (
372- ( resolved ) => buildDataResponse ( exeContext , resolved ) ,
375+ ( resolved ) => {
376+ exeContext . completed = true ;
377+ return buildDataResponse ( exeContext , resolved ) ;
378+ } ,
373379 ( error : unknown ) => {
380+ exeContext . completed = true ;
374381 exeContext . promiseCanceller ?. disconnect ( ) ;
375382 return {
376383 data : null ,
@@ -379,8 +386,10 @@ export function experimentalExecuteQueryOrMutationOrSubscriptionEvent(
379386 } ,
380387 ) ;
381388 }
389+ exeContext . completed = true ;
382390 return buildDataResponse ( exeContext , graphqlWrappedResult ) ;
383391 } catch ( error ) {
392+ exeContext . completed = true ;
384393 // TODO: add test case for synchronous null bubbling to root with cancellation
385394 /* c8 ignore next */
386395 exeContext . promiseCanceller ?. disconnect ( ) ;
@@ -1761,6 +1770,10 @@ function completeObjectValue(
17611770 incrementalContext : IncrementalContext | undefined ,
17621771 deferMap : ReadonlyMap < DeferUsage , DeferredFragmentRecord > | undefined ,
17631772) : PromiseOrValue < GraphQLWrappedResult < ObjMap < unknown > > > {
1773+ if ( ( incrementalContext ?? exeContext ) . completed ) {
1774+ throw new Error ( 'Completed, aborting.' ) ;
1775+ }
1776+
17641777 // If there is an isTypeOf predicate function, call it with the
17651778 // current result. If isTypeOf returns false, then raise an error rather
17661779 // than continuing execution.
@@ -2280,6 +2293,7 @@ function collectExecutionGroups(
22802293 groupedFieldSet ,
22812294 {
22822295 errors : undefined ,
2296+ completed : false ,
22832297 deferUsageSet,
22842298 } ,
22852299 deferMap ,
@@ -2339,6 +2353,7 @@ function executeExecutionGroup(
23392353 deferMap ,
23402354 ) ;
23412355 } catch ( error ) {
2356+ incrementalContext . completed = true ;
23422357 return {
23432358 pendingExecutionGroup,
23442359 path : pathToArray ( path ) ,
@@ -2348,21 +2363,27 @@ function executeExecutionGroup(
23482363
23492364 if ( isPromise ( result ) ) {
23502365 return result . then (
2351- ( resolved ) =>
2352- buildCompletedExecutionGroup (
2366+ ( resolved ) => {
2367+ incrementalContext . completed = true ;
2368+ return buildCompletedExecutionGroup (
23532369 incrementalContext . errors ,
23542370 pendingExecutionGroup ,
23552371 path ,
23562372 resolved ,
2357- ) ,
2358- ( error : unknown ) => ( {
2359- pendingExecutionGroup,
2360- path : pathToArray ( path ) ,
2361- errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2362- } ) ,
2373+ ) ;
2374+ } ,
2375+ ( error : unknown ) => {
2376+ incrementalContext . completed = true ;
2377+ return {
2378+ pendingExecutionGroup,
2379+ path : pathToArray ( path ) ,
2380+ errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2381+ } ;
2382+ } ,
23632383 ) ;
23642384 }
23652385
2386+ incrementalContext . completed = true ;
23662387 return buildCompletedExecutionGroup (
23672388 incrementalContext . errors ,
23682389 pendingExecutionGroup ,
@@ -2417,7 +2438,7 @@ function buildSyncStreamItemQueue(
24172438 initialPath ,
24182439 initialItem ,
24192440 exeContext ,
2420- { errors : undefined } ,
2441+ { errors : undefined , completed : false } ,
24212442 fieldDetailsList ,
24222443 info ,
24232444 itemType ,
@@ -2448,7 +2469,7 @@ function buildSyncStreamItemQueue(
24482469 itemPath ,
24492470 value ,
24502471 exeContext ,
2451- { errors : undefined } ,
2472+ { errors : undefined , completed : false } ,
24522473 fieldDetailsList ,
24532474 info ,
24542475 itemType ,
@@ -2540,7 +2561,7 @@ async function getNextAsyncStreamItemResult(
25402561 itemPath ,
25412562 iteration . value ,
25422563 exeContext ,
2543- { errors : undefined } ,
2564+ { errors : undefined , completed : false } ,
25442565 fieldDetailsList ,
25452566 info ,
25462567 itemType ,
@@ -2587,11 +2608,16 @@ function completeStreamItem(
25872608 incrementalContext ,
25882609 new Map ( ) ,
25892610 ) . then (
2590- ( resolvedItem ) =>
2591- buildStreamItemResult ( incrementalContext . errors , resolvedItem ) ,
2592- ( error : unknown ) => ( {
2593- errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2594- } ) ,
2611+ ( resolvedItem ) => {
2612+ incrementalContext . completed = true ;
2613+ return buildStreamItemResult ( incrementalContext . errors , resolvedItem ) ;
2614+ } ,
2615+ ( error : unknown ) => {
2616+ incrementalContext . completed = true ;
2617+ return {
2618+ errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2619+ } ;
2620+ } ,
25952621 ) ;
25962622 }
25972623
@@ -2620,6 +2646,7 @@ function completeStreamItem(
26202646 result = { rawResult : null , incrementalDataRecords : undefined } ;
26212647 }
26222648 } catch ( error ) {
2649+ incrementalContext . completed = true ;
26232650 return {
26242651 errors : withError ( incrementalContext . errors , error ) ,
26252652 } ;
@@ -2639,14 +2666,20 @@ function completeStreamItem(
26392666 return { rawResult : null , incrementalDataRecords : undefined } ;
26402667 } )
26412668 . then (
2642- ( resolvedItem ) =>
2643- buildStreamItemResult ( incrementalContext . errors , resolvedItem ) ,
2644- ( error : unknown ) => ( {
2645- errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2646- } ) ,
2669+ ( resolvedItem ) => {
2670+ incrementalContext . completed = true ;
2671+ return buildStreamItemResult ( incrementalContext . errors , resolvedItem ) ;
2672+ } ,
2673+ ( error : unknown ) => {
2674+ incrementalContext . completed = true ;
2675+ return {
2676+ errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2677+ } ;
2678+ } ,
26472679 ) ;
26482680 }
26492681
2682+ incrementalContext . completed = true ;
26502683 return buildStreamItemResult ( incrementalContext . errors , result ) ;
26512684}
26522685
0 commit comments