@@ -1950,59 +1950,49 @@ function executeStreamField(
19501950 return asyncPayloadRecord ;
19511951}
19521952
1953- async function executeStreamIteratorItem (
1953+ async function completedItemsFromPromisedCompletedStreamedItem (
19541954 iterator : AsyncIterator < unknown > ,
19551955 exeContext : ExecutionContext ,
1956- fieldNodes : ReadonlyArray < FieldNode > ,
1957- info : GraphQLResolveInfo ,
19581956 itemType : GraphQLOutputType ,
1959- asyncPayloadRecord : StreamRecord ,
1957+ fieldNodes : ReadonlyArray < FieldNode > ,
1958+ path : Path ,
19601959 itemPath : Path ,
1961- ) : Promise < IteratorResult < unknown > > {
1962- let item ;
1960+ completedItem : Promise < unknown > ,
1961+ asyncPayloadRecord : AsyncPayloadRecord ,
1962+ ) : Promise < [ unknown ] | null > {
19631963 try {
1964- const { value, done } = await iterator . next ( ) ;
1965- if ( done ) {
1966- asyncPayloadRecord . setIsCompletedIterator ( ) ;
1967- return { done, value : undefined } ;
1964+ try {
1965+ return [ await completedItem ] ;
1966+ } catch ( rawError ) {
1967+ const error = locatedError ( rawError , fieldNodes , pathToArray ( itemPath ) ) ;
1968+ const handledError = handleFieldError (
1969+ error ,
1970+ itemType ,
1971+ asyncPayloadRecord . errors ,
1972+ ) ;
1973+ filterSubsequentPayloads ( exeContext , itemPath , asyncPayloadRecord ) ;
1974+ return [ handledError ] ;
19681975 }
1969- item = value ;
1970- } catch ( rawError ) {
1971- const error = locatedError ( rawError , fieldNodes , pathToArray ( itemPath ) ) ;
1972- const value = handleFieldError ( error , itemType , asyncPayloadRecord . errors ) ;
1973- // don't continue if iterator throws
1974- return { done : true , value } ;
1976+ } catch ( error ) {
1977+ handleStreamError ( iterator , exeContext , path , asyncPayloadRecord , error ) ;
1978+ return null ;
19751979 }
1976- let completedItem ;
1977- try {
1978- completedItem = completeValue (
1979- exeContext ,
1980- itemType ,
1981- fieldNodes ,
1982- info ,
1983- itemPath ,
1984- item ,
1985- asyncPayloadRecord ,
1986- ) ;
1980+ }
19871981
1988- if ( isPromise ( completedItem ) ) {
1989- completedItem = completedItem . then ( undefined , ( rawError ) => {
1990- const error = locatedError ( rawError , fieldNodes , pathToArray ( itemPath ) ) ;
1991- const handledError = handleFieldError (
1992- error ,
1993- itemType ,
1994- asyncPayloadRecord . errors ,
1995- ) ;
1996- filterSubsequentPayloads ( exeContext , itemPath , asyncPayloadRecord ) ;
1997- return handledError ;
1998- } ) ;
1999- }
2000- return { done : false , value : completedItem } ;
2001- } catch ( rawError ) {
2002- const error = locatedError ( rawError , fieldNodes , pathToArray ( itemPath ) ) ;
2003- const value = handleFieldError ( error , itemType , asyncPayloadRecord . errors ) ;
2004- filterSubsequentPayloads ( exeContext , itemPath , asyncPayloadRecord ) ;
2005- return { done : false , value } ;
1982+ function handleStreamError (
1983+ iterator : AsyncIterator < unknown > ,
1984+ exeContext : ExecutionContext ,
1985+ path : Path ,
1986+ asyncPayloadRecord : AsyncPayloadRecord ,
1987+ error : GraphQLError ,
1988+ ) : void {
1989+ asyncPayloadRecord . errors . push ( error ) ;
1990+ filterSubsequentPayloads ( exeContext , path , asyncPayloadRecord ) ;
1991+ // entire stream has errored and bubbled upwards
1992+ if ( iterator ?. return ) {
1993+ iterator . return ( ) . catch ( ( ) => {
1994+ // ignore errors
1995+ } ) ;
20061996 }
20071997}
20081998
@@ -2032,50 +2022,73 @@ async function executeStreamIterator(
20322022
20332023 let iteration ;
20342024 try {
2035- // eslint-disable-next-line no-await-in-loop
2036- iteration = await executeStreamIteratorItem (
2037- iterator ,
2038- exeContext ,
2039- fieldNodes ,
2040- info ,
2041- itemType ,
2042- asyncPayloadRecord ,
2043- itemPath ,
2044- ) ;
2045- } catch ( error ) {
2046- asyncPayloadRecord . errors . push ( error ) ;
2047- filterSubsequentPayloads ( exeContext , path , asyncPayloadRecord ) ;
2048- asyncPayloadRecord . addItems ( null ) ;
2049- // entire stream has errored and bubbled upwards
2050- if ( iterator ?. return ) {
2051- iterator . return ( ) . catch ( ( ) => {
2052- // ignore errors
2053- } ) ;
2025+ try {
2026+ // eslint-disable-next-line no-await-in-loop
2027+ iteration = await iterator . next ( ) ;
2028+ } catch ( rawError ) {
2029+ const error = locatedError ( rawError , fieldNodes , pathToArray ( itemPath ) ) ;
2030+ const value = handleFieldError (
2031+ error ,
2032+ itemType ,
2033+ asyncPayloadRecord . errors ,
2034+ ) ;
2035+ // don't continue if iterator throws
2036+ asyncPayloadRecord . addItems ( [ value ] ) ;
2037+ break ;
20542038 }
2055- return ;
2056- }
20572039
2058- const { done, value : completedItem } = iteration ;
2040+ const { done, value : item } = iteration ;
20592041
2060- let completedItems : PromiseOrValue < Array < unknown > | null > ;
2061- if ( isPromise ( completedItem ) ) {
2062- completedItems = completedItem . then (
2063- ( value ) => [ value ] ,
2064- ( error ) => {
2065- asyncPayloadRecord . errors . push ( error ) ;
2066- filterSubsequentPayloads ( exeContext , path , asyncPayloadRecord ) ;
2067- return null ;
2068- } ,
2069- ) ;
2070- } else {
2071- completedItems = [ completedItem ] ;
2072- }
2042+ if ( done ) {
2043+ asyncPayloadRecord . setIsCompletedIterator ( ) ;
2044+ asyncPayloadRecord . addItems ( [ item ] ) ;
2045+ break ;
2046+ }
20732047
2074- asyncPayloadRecord . addItems ( completedItems ) ;
2048+ let completedItem ;
2049+ try {
2050+ completedItem = completeValue (
2051+ exeContext ,
2052+ itemType ,
2053+ fieldNodes ,
2054+ info ,
2055+ itemPath ,
2056+ item ,
2057+ asyncPayloadRecord ,
2058+ ) ;
2059+ } catch ( rawError ) {
2060+ const error = locatedError ( rawError , fieldNodes , pathToArray ( itemPath ) ) ;
2061+ completedItem = handleFieldError (
2062+ error ,
2063+ itemType ,
2064+ asyncPayloadRecord . errors ,
2065+ ) ;
2066+ filterSubsequentPayloads ( exeContext , itemPath , asyncPayloadRecord ) ;
2067+ }
20752068
2076- if ( done ) {
2077- break ;
2069+ let completedItems : PromiseOrValue < Array < unknown > | null > ;
2070+ if ( isPromise ( completedItem ) ) {
2071+ completedItems = completedItemsFromPromisedCompletedStreamedItem (
2072+ iterator ,
2073+ exeContext ,
2074+ itemType ,
2075+ fieldNodes ,
2076+ path ,
2077+ itemPath ,
2078+ completedItem ,
2079+ asyncPayloadRecord ,
2080+ ) ;
2081+ } else {
2082+ completedItems = [ completedItem ] ;
2083+ }
2084+
2085+ asyncPayloadRecord . addItems ( completedItems ) ;
2086+ } catch ( error ) {
2087+ handleStreamError ( iterator , exeContext , path , asyncPayloadRecord , error ) ;
2088+ asyncPayloadRecord . addItems ( null ) ;
2089+ return ;
20782090 }
2091+
20792092 previousAsyncPayloadRecord = asyncPayloadRecord ;
20802093 index ++ ;
20812094 }
0 commit comments