@@ -165,11 +165,13 @@ export interface ExecutionContext {
165165 validatedExecutionArgs : ValidatedExecutionArgs ;
166166 errors : Array < GraphQLError > | undefined ;
167167 canceller : Canceller | 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
@@ -317,6 +319,7 @@ export function experimentalExecuteQueryOrMutationOrSubscriptionEvent(
317319 validatedExecutionArgs,
318320 errors : undefined ,
319321 canceller : abortSignal ? new Canceller ( abortSignal ) : undefined ,
322+ completed : false ,
320323 cancellableStreams : undefined ,
321324 } ;
322325 try {
@@ -367,8 +370,12 @@ export function experimentalExecuteQueryOrMutationOrSubscriptionEvent(
367370
368371 if ( isPromise ( graphqlWrappedResult ) ) {
369372 return graphqlWrappedResult . then (
370- ( resolved ) => buildDataResponse ( exeContext , resolved ) ,
373+ ( resolved ) => {
374+ exeContext . completed = true ;
375+ return buildDataResponse ( exeContext , resolved ) ;
376+ } ,
371377 ( error : unknown ) => {
378+ exeContext . completed = true ;
372379 exeContext . canceller ?. unsubscribe ( ) ;
373380 return {
374381 data : null ,
@@ -377,8 +384,10 @@ export function experimentalExecuteQueryOrMutationOrSubscriptionEvent(
377384 } ,
378385 ) ;
379386 }
387+ exeContext . completed = true ;
380388 return buildDataResponse ( exeContext , graphqlWrappedResult ) ;
381389 } catch ( error ) {
390+ exeContext . completed = true ;
382391 // TODO: add test case for synchronous null bubbling to root with cancellation
383392 /* c8 ignore next */
384393 exeContext . canceller ?. unsubscribe ( ) ;
@@ -1757,6 +1766,10 @@ function completeObjectValue(
17571766 incrementalContext : IncrementalContext | undefined ,
17581767 deferMap : ReadonlyMap < DeferUsage , DeferredFragmentRecord > | undefined ,
17591768) : PromiseOrValue < GraphQLWrappedResult < ObjMap < unknown > > > {
1769+ if ( ( incrementalContext ?? exeContext ) . completed ) {
1770+ throw new Error ( 'Completed, aborting.' ) ;
1771+ }
1772+
17601773 // If there is an isTypeOf predicate function, call it with the
17611774 // current result. If isTypeOf returns false, then raise an error rather
17621775 // than continuing execution.
@@ -2274,6 +2287,7 @@ function collectExecutionGroups(
22742287 groupedFieldSet ,
22752288 {
22762289 errors : undefined ,
2290+ completed : false ,
22772291 deferUsageSet,
22782292 } ,
22792293 deferMap ,
@@ -2333,6 +2347,7 @@ function executeExecutionGroup(
23332347 deferMap ,
23342348 ) ;
23352349 } catch ( error ) {
2350+ incrementalContext . completed = true ;
23362351 return {
23372352 pendingExecutionGroup,
23382353 path : pathToArray ( path ) ,
@@ -2342,21 +2357,27 @@ function executeExecutionGroup(
23422357
23432358 if ( isPromise ( result ) ) {
23442359 return result . then (
2345- ( resolved ) =>
2346- buildCompletedExecutionGroup (
2360+ ( resolved ) => {
2361+ incrementalContext . completed = true ;
2362+ return buildCompletedExecutionGroup (
23472363 incrementalContext . errors ,
23482364 pendingExecutionGroup ,
23492365 path ,
23502366 resolved ,
2351- ) ,
2352- ( error : unknown ) => ( {
2353- pendingExecutionGroup,
2354- path : pathToArray ( path ) ,
2355- errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2356- } ) ,
2367+ ) ;
2368+ } ,
2369+ ( error : unknown ) => {
2370+ incrementalContext . completed = true ;
2371+ return {
2372+ pendingExecutionGroup,
2373+ path : pathToArray ( path ) ,
2374+ errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2375+ } ;
2376+ } ,
23572377 ) ;
23582378 }
23592379
2380+ incrementalContext . completed = true ;
23602381 return buildCompletedExecutionGroup (
23612382 incrementalContext . errors ,
23622383 pendingExecutionGroup ,
@@ -2411,7 +2432,7 @@ function buildSyncStreamItemQueue(
24112432 initialPath ,
24122433 initialItem ,
24132434 exeContext ,
2414- { errors : undefined } ,
2435+ { errors : undefined , completed : false } ,
24152436 fieldDetailsList ,
24162437 info ,
24172438 itemType ,
@@ -2442,7 +2463,7 @@ function buildSyncStreamItemQueue(
24422463 itemPath ,
24432464 value ,
24442465 exeContext ,
2445- { errors : undefined } ,
2466+ { errors : undefined , completed : false } ,
24462467 fieldDetailsList ,
24472468 info ,
24482469 itemType ,
@@ -2534,7 +2555,7 @@ async function getNextAsyncStreamItemResult(
25342555 itemPath ,
25352556 iteration . value ,
25362557 exeContext ,
2537- { errors : undefined } ,
2558+ { errors : undefined , completed : false } ,
25382559 fieldDetailsList ,
25392560 info ,
25402561 itemType ,
@@ -2581,11 +2602,16 @@ function completeStreamItem(
25812602 incrementalContext ,
25822603 new Map ( ) ,
25832604 ) . then (
2584- ( resolvedItem ) =>
2585- buildStreamItemResult ( incrementalContext . errors , resolvedItem ) ,
2586- ( error : unknown ) => ( {
2587- errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2588- } ) ,
2605+ ( resolvedItem ) => {
2606+ incrementalContext . completed = true ;
2607+ return buildStreamItemResult ( incrementalContext . errors , resolvedItem ) ;
2608+ } ,
2609+ ( error : unknown ) => {
2610+ incrementalContext . completed = true ;
2611+ return {
2612+ errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2613+ } ;
2614+ } ,
25892615 ) ;
25902616 }
25912617
@@ -2614,6 +2640,7 @@ function completeStreamItem(
26142640 result = { rawResult : null , incrementalDataRecords : undefined } ;
26152641 }
26162642 } catch ( error ) {
2643+ incrementalContext . completed = true ;
26172644 return {
26182645 errors : withError ( incrementalContext . errors , error ) ,
26192646 } ;
@@ -2633,14 +2660,20 @@ function completeStreamItem(
26332660 return { rawResult : null , incrementalDataRecords : undefined } ;
26342661 } )
26352662 . then (
2636- ( resolvedItem ) =>
2637- buildStreamItemResult ( incrementalContext . errors , resolvedItem ) ,
2638- ( error : unknown ) => ( {
2639- errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2640- } ) ,
2663+ ( resolvedItem ) => {
2664+ incrementalContext . completed = true ;
2665+ return buildStreamItemResult ( incrementalContext . errors , resolvedItem ) ;
2666+ } ,
2667+ ( error : unknown ) => {
2668+ incrementalContext . completed = true ;
2669+ return {
2670+ errors : withError ( incrementalContext . errors , error as GraphQLError ) ,
2671+ } ;
2672+ } ,
26412673 ) ;
26422674 }
26432675
2676+ incrementalContext . completed = true ;
26442677 return buildStreamItemResult ( incrementalContext . errors , result ) ;
26452678}
26462679
0 commit comments