@@ -275,7 +275,7 @@ export function graphqlHTTP(options: Options): Middleware {
275275 // https://graphql.github.io/graphql-spec/#sec-Response-Format
276276 if ( optionsData . extensions ) {
277277 extensionsFn = ( payload : AsyncExecutionResult ) => {
278- /* istanbul ignore next condition not reachable, required for flow */
278+ /* istanbul ignore else: condition not reachable, required for typescript */
279279 if ( optionsData . extensions ) {
280280 return optionsData . extensions ( {
281281 document : documentAST ,
@@ -285,6 +285,8 @@ export function graphqlHTTP(options: Options): Middleware {
285285 context,
286286 } ) ;
287287 }
288+ /* istanbul ignore next: condition not reachable, required for typescript */
289+ return undefined ;
288290 } ;
289291 }
290292
@@ -362,23 +364,25 @@ export function graphqlHTTP(options: Options): Middleware {
362364 fieldResolver,
363365 typeResolver,
364366 } ) ;
367+
368+ if ( isAsyncIterable ( executeResult ) ) {
369+ // Get first payload from AsyncIterator. http status will reflect status
370+ // of this payload.
371+ const asyncIterator = getAsyncIterator < ExecutionResult > (
372+ executeResult ,
373+ ) ;
374+ const { value } = await asyncIterator . next ( ) ;
375+ result = value ;
376+ } else {
377+ result = executeResult ;
378+ }
365379 } catch ( contextError : unknown ) {
366380 // Return 400: Bad Request if any execution context errors exist.
367381 throw httpError ( 400 , 'GraphQL execution context error.' , {
368382 graphqlErrors : [ contextError ] ,
369383 } ) ;
370384 }
371385
372- if ( isAsyncIterable ( executeResult ) ) {
373- // Get first payload from AsyncIterator. http status will reflect status
374- // of this payload.
375- const asyncIterator = getAsyncIterator < ExecutionResult > ( executeResult ) ;
376- const { value } = await asyncIterator . next ( ) ;
377- result = value ;
378- } else {
379- result = executeResult ;
380- }
381-
382386 if ( extensionsFn ) {
383387 const extensions = await extensionsFn ( result ) ;
384388
@@ -412,9 +416,12 @@ export function graphqlHTTP(options: Options): Middleware {
412416 undefined ,
413417 error ,
414418 ) ;
415- result = { data : undefined , errors : [ graphqlError ] } ;
419+ executeResult = result = { data : undefined , errors : [ graphqlError ] } ;
416420 } else {
417- result = { data : undefined , errors : error . graphqlErrors } ;
421+ executeResult = result = {
422+ data : undefined ,
423+ errors : error . graphqlErrors ,
424+ } ;
418425 }
419426 }
420427
@@ -436,22 +443,41 @@ export function graphqlHTTP(options: Options): Middleware {
436443 if ( isAsyncIterable ( executeResult ) ) {
437444 response . setHeader ( 'Content-Type' , 'multipart/mixed; boundary="-"' ) ;
438445 sendPartialResponse ( pretty , response , formattedResult ) ;
439- for await ( let payload of executeResult ) {
440- // Collect and apply any metadata extensions if a function was provided.
441- // https://graphql.github.io/graphql-spec/#sec-Response-Format
442- if ( extensionsFn ) {
443- const extensions = await extensionsFn ( payload ) ;
444-
445- if ( extensions != null ) {
446- payload = { ...payload , extensions } ;
446+ try {
447+ for await ( let payload of executeResult ) {
448+ // Collect and apply any metadata extensions if a function was provided.
449+ // https://graphql.github.io/graphql-spec/#sec-Response-Format
450+ if ( extensionsFn ) {
451+ const extensions = await extensionsFn ( payload ) ;
452+
453+ if ( extensions != null ) {
454+ payload = { ...payload , extensions } ;
455+ }
447456 }
457+ const formattedPayload : FormattedExecutionPatchResult = {
458+ // first payload is already consumed, all subsequent payloads typed as ExecutionPatchResult
459+ ...( payload as ExecutionPatchResult ) ,
460+ errors : payload . errors ?. map ( formatErrorFn ) ,
461+ } ;
462+ sendPartialResponse ( pretty , response , formattedPayload ) ;
448463 }
449- const formattedPayload : FormattedExecutionPatchResult = {
450- // first payload is already consumed, all subsequent payloads typed as ExecutionPatchResult
451- ...( payload as ExecutionPatchResult ) ,
452- errors : payload . errors ?. map ( formatErrorFn ) ,
453- } ;
454- sendPartialResponse ( pretty , response , formattedPayload ) ;
464+ } catch ( rawError : unknown ) {
465+ /* istanbul ignore next: Thrown by underlying library. */
466+ const error =
467+ rawError instanceof Error ? rawError : new Error ( String ( rawError ) ) ;
468+ const graphqlError = new GraphQLError (
469+ error . message ,
470+ undefined ,
471+ undefined ,
472+ undefined ,
473+ undefined ,
474+ error ,
475+ ) ;
476+ sendPartialResponse ( pretty , response , {
477+ data : undefined ,
478+ errors : [ formatErrorFn ( graphqlError ) ] ,
479+ hasNext : false ,
480+ } ) ;
455481 }
456482 response . write ( '\r\n-----\r\n' ) ;
457483 response . end ( ) ;
0 commit comments