@@ -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 {
@@ -359,8 +362,12 @@ export function experimentalExecuteQueryOrMutationOrSubscriptionEvent(
359362
360363 if ( isPromise ( graphqlWrappedResult ) ) {
361364 return graphqlWrappedResult . then (
362- ( resolved ) => buildDataResponse ( exeContext , resolved ) ,
365+ ( resolved ) => {
366+ exeContext . completed = true ;
367+ return buildDataResponse ( exeContext , resolved ) ;
368+ } ,
363369 ( error : unknown ) => {
370+ exeContext . completed = true ;
364371 exeContext . promiseCanceller ?. disconnect ( ) ;
365372 return {
366373 data : null ,
@@ -369,8 +376,10 @@ export function experimentalExecuteQueryOrMutationOrSubscriptionEvent(
369376 } ,
370377 ) ;
371378 }
379+ exeContext . completed = true ;
372380 return buildDataResponse ( exeContext , graphqlWrappedResult ) ;
373381 } catch ( error ) {
382+ exeContext . completed = true ;
374383 // TODO: add test case for synchronous null bubbling to root with cancellation
375384 /* c8 ignore next */
376385 exeContext . promiseCanceller ?. disconnect ( ) ;
@@ -1760,6 +1769,10 @@ function completeObjectValue(
17601769 incrementalContext : IncrementalContext | undefined ,
17611770 deferMap : ReadonlyMap < DeferUsage , DeferredFragmentRecord > | undefined ,
17621771) : PromiseOrValue < GraphQLWrappedResult < ObjMap < unknown > > > {
1772+ if ( ( incrementalContext ?? exeContext ) . completed ) {
1773+ throw new Error ( 'Completed, aborting.' ) ;
1774+ }
1775+
17631776 // If there is an isTypeOf predicate function, call it with the
17641777 // current result. If isTypeOf returns false, then raise an error rather
17651778 // than continuing execution.
@@ -2324,6 +2337,7 @@ function collectExecutionGroups(
23242337 groupedFieldSet ,
23252338 {
23262339 errors : undefined ,
2340+ completed : false ,
23272341 deferUsageSet,
23282342 } ,
23292343 deferMap ,
@@ -2383,6 +2397,7 @@ function executeExecutionGroup(
23832397 deferMap ,
23842398 ) ;
23852399 } catch ( error ) {
2400+ incrementalContext . completed = true ;
23862401 return {
23872402 pendingExecutionGroup,
23882403 path : pathToArray ( path ) ,
@@ -2392,21 +2407,27 @@ function executeExecutionGroup(
23922407
23932408 if ( isPromise ( result ) ) {
23942409 return result . then (
2395- ( resolved ) =>
2396- buildCompletedExecutionGroup (
2410+ ( resolved ) => {
2411+ incrementalContext . completed = true ;
2412+ return buildCompletedExecutionGroup (
23972413 incrementalContext . errors ,
23982414 pendingExecutionGroup ,
23992415 path ,
24002416 resolved ,
2401- ) ,
2402- ( error : unknown ) => ( {
2403- pendingExecutionGroup,
2404- path : pathToArray ( path ) ,
2405- errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2406- } ) ,
2417+ ) ;
2418+ } ,
2419+ ( error : unknown ) => {
2420+ incrementalContext . completed = true ;
2421+ return {
2422+ pendingExecutionGroup,
2423+ path : pathToArray ( path ) ,
2424+ errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2425+ } ;
2426+ } ,
24072427 ) ;
24082428 }
24092429
2430+ incrementalContext . completed = true ;
24102431 return buildCompletedExecutionGroup (
24112432 incrementalContext . errors ,
24122433 pendingExecutionGroup ,
@@ -2461,7 +2482,7 @@ function buildSyncStreamItemQueue(
24612482 initialPath ,
24622483 initialItem ,
24632484 exeContext ,
2464- { errors : undefined } ,
2485+ { errors : undefined , completed : false } ,
24652486 fieldDetailsList ,
24662487 info ,
24672488 itemType ,
@@ -2492,7 +2513,7 @@ function buildSyncStreamItemQueue(
24922513 itemPath ,
24932514 value ,
24942515 exeContext ,
2495- { errors : undefined } ,
2516+ { errors : undefined , completed : false } ,
24962517 fieldDetailsList ,
24972518 info ,
24982519 itemType ,
@@ -2584,7 +2605,7 @@ async function getNextAsyncStreamItemResult(
25842605 itemPath ,
25852606 iteration . value ,
25862607 exeContext ,
2587- { errors : undefined } ,
2608+ { errors : undefined , completed : false } ,
25882609 fieldDetailsList ,
25892610 info ,
25902611 itemType ,
@@ -2631,11 +2652,16 @@ function completeStreamItem(
26312652 incrementalContext ,
26322653 new Map ( ) ,
26332654 ) . then (
2634- ( resolvedItem ) =>
2635- buildStreamItemResult ( incrementalContext . errors , resolvedItem ) ,
2636- ( error : unknown ) => ( {
2637- errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2638- } ) ,
2655+ ( resolvedItem ) => {
2656+ incrementalContext . completed = true ;
2657+ return buildStreamItemResult ( incrementalContext . errors , resolvedItem ) ;
2658+ } ,
2659+ ( error : unknown ) => {
2660+ incrementalContext . completed = true ;
2661+ return {
2662+ errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2663+ } ;
2664+ } ,
26392665 ) ;
26402666 }
26412667
@@ -2664,6 +2690,7 @@ function completeStreamItem(
26642690 result = { rawResult : null , incrementalDataRecords : undefined } ;
26652691 }
26662692 } catch ( error ) {
2693+ incrementalContext . completed = true ;
26672694 return {
26682695 errors : withError ( incrementalContext . errors , error ) ,
26692696 } ;
@@ -2683,14 +2710,20 @@ function completeStreamItem(
26832710 return { rawResult : null , incrementalDataRecords : undefined } ;
26842711 } )
26852712 . then (
2686- ( resolvedItem ) =>
2687- buildStreamItemResult ( incrementalContext . errors , resolvedItem ) ,
2688- ( error : unknown ) => ( {
2689- errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2690- } ) ,
2713+ ( resolvedItem ) => {
2714+ incrementalContext . completed = true ;
2715+ return buildStreamItemResult ( incrementalContext . errors , resolvedItem ) ;
2716+ } ,
2717+ ( error : unknown ) => {
2718+ incrementalContext . completed = true ;
2719+ return {
2720+ errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2721+ } ;
2722+ } ,
26912723 ) ;
26922724 }
26932725
2726+ incrementalContext . completed = true ;
26942727 return buildStreamItemResult ( incrementalContext . errors , result ) ;
26952728}
26962729
0 commit comments