@@ -198,33 +198,36 @@ export interface FormattedExecutionResult<
198198/** @internal */
199199export class Executor {
200200 validatedExecutionArgs : ValidatedExecutionArgs ;
201- onExternalAbort : ( ( ) => void ) | undefined ;
202201 finished : boolean ;
203- abortControllers : Set < AbortController > ;
202+ resolverAbortControllers : Set < AbortController > ;
204203 collectedErrors : CollectedErrors ;
205204
206205 constructor ( validatedExecutionArgs : ValidatedExecutionArgs ) {
207206 this . validatedExecutionArgs = validatedExecutionArgs ;
208- this . onExternalAbort = undefined ;
209207 this . finished = false ;
210- this . abortControllers = new Set ( ) ;
208+ this . resolverAbortControllers = new Set ( ) ;
211209 this . collectedErrors = new CollectedErrors ( ) ;
212210 }
213211
214212 executeQueryOrMutationOrSubscriptionEvent ( ) : PromiseOrValue < ExecutionResult > {
215213 const validatedExecutionArgs = this . validatedExecutionArgs ;
216214 const externalAbortSignal = validatedExecutionArgs . externalAbortSignal ;
215+ let removeAbortListener : ( ( ) => void ) | undefined ;
217216 if ( externalAbortSignal ) {
218217 if ( externalAbortSignal . aborted ) {
219218 throw new Error ( externalAbortSignal . reason ) ;
220219 }
221- const onExternalAbort = ( ) => {
222- this . cancel ( externalAbortSignal . reason ) ;
223- } ;
220+ const onExternalAbort = ( ) => this . cancel ( externalAbortSignal . reason ) ;
221+ removeAbortListener = ( ) =>
222+ externalAbortSignal . removeEventListener ( 'abort' , onExternalAbort ) ;
224223 externalAbortSignal . addEventListener ( 'abort' , onExternalAbort ) ;
225- this . onExternalAbort = onExternalAbort ;
226224 }
227225
226+ const onFinish = ( ) => {
227+ removeAbortListener ?.( ) ;
228+ this . finish ( ) ;
229+ } ;
230+
228231 try {
229232 const {
230233 schema,
@@ -264,11 +267,11 @@ export class Executor {
264267 if ( isPromise ( result ) ) {
265268 const promise = result . then (
266269 ( data ) => {
267- this . finish ( ) ;
270+ onFinish ( ) ;
268271 return this . buildResponse ( data ) ;
269272 } ,
270273 ( error : unknown ) => {
271- this . finish ( ) ;
274+ onFinish ( ) ;
272275 this . collectedErrors . add ( error as GraphQLError , undefined ) ;
273276 return this . buildResponse ( null ) ;
274277 } ,
@@ -277,9 +280,11 @@ export class Executor {
277280 ? cancellablePromise ( promise , externalAbortSignal )
278281 : promise ;
279282 }
283+ onFinish ( ) ;
280284 return this . buildResponse ( result ) ;
281285 } catch ( error ) {
282286 this . collectedErrors . add ( error as GraphQLError , undefined ) ;
287+ onFinish ( ) ;
283288 return this . buildResponse ( null ) ;
284289 }
285290 }
@@ -291,24 +296,20 @@ export class Executor {
291296 }
292297
293298 finish ( reason ?: unknown ) : void {
294- if ( this . finished ) {
295- return ;
299+ if ( ! this . finished ) {
300+ this . finished = true ;
301+ this . triggerResolverAbortSignals ( reason ) ;
296302 }
297- this . finished = true ;
298- const { abortControllers, onExternalAbort } = this ;
303+ }
304+
305+ triggerResolverAbortSignals ( reason ?: unknown ) : void {
306+ const { resolverAbortControllers } = this ;
299307 const finishReason =
300308 reason ?? new Error ( 'Execution has already completed.' ) ;
301- for ( const abortController of abortControllers ) {
309+ for ( const abortController of resolverAbortControllers ) {
302310 abortController . abort ( finishReason ) ;
303311 }
304- if ( onExternalAbort ) {
305- this . validatedExecutionArgs . externalAbortSignal ?. removeEventListener (
306- 'abort' ,
307- onExternalAbort ,
308- ) ;
309- }
310312 }
311-
312313 /**
313314 * Given a completed execution context and data, build the `{ errors, data }`
314315 * response defined by the "Response" section of the GraphQL specification.
@@ -480,11 +481,11 @@ export class Executor {
480481 throw new Error ( 'Execution has already completed.' ) ;
481482 }
482483 const abortController = new AbortController ( ) ;
483- this . abortControllers . add ( abortController ) ;
484+ this . resolverAbortControllers . add ( abortController ) ;
484485 return {
485486 abortSignal : abortController . signal ,
486487 unregister : ( ) => {
487- this . abortControllers . delete ( abortController ) ;
488+ this . resolverAbortControllers . delete ( abortController ) ;
488489 } ,
489490 } ;
490491 } ,
0 commit comments