@@ -922,6 +922,41 @@ function completeValue(
922
922
) ;
923
923
}
924
924
925
+ async function completePromiseCatchingErrors (
926
+ exeContext : ExecutionContext ,
927
+ returnType : GraphQLOutputType ,
928
+ fieldNodes : ReadonlyArray < FieldNode > ,
929
+ info : GraphQLResolveInfo ,
930
+ path : Path ,
931
+ result : Promise < unknown > ,
932
+ asyncPayloadRecord ?: AsyncPayloadRecord ,
933
+ ) : Promise < unknown > {
934
+ try {
935
+ const resolved = await result ;
936
+ let completed = completeValue (
937
+ exeContext ,
938
+ returnType ,
939
+ fieldNodes ,
940
+ info ,
941
+ path ,
942
+ resolved ,
943
+ asyncPayloadRecord ,
944
+ ) ;
945
+ if ( isPromise ( completed ) ) {
946
+ // see: https://github.com/tc39/proposal-faster-promise-adoption
947
+ // it is faster to await a promise prior to returning it from an async function
948
+ completed = await completed ;
949
+ }
950
+ return completed ;
951
+ } catch ( rawError ) {
952
+ const errors = asyncPayloadRecord ?. errors ?? exeContext . errors ;
953
+ const error = locatedError ( rawError , fieldNodes , pathToArray ( path ) ) ;
954
+ const handledError = handleFieldError ( error , returnType , errors ) ;
955
+ filterSubsequentPayloads ( exeContext , path , asyncPayloadRecord ) ;
956
+ return handledError ;
957
+ }
958
+ }
959
+
925
960
/**
926
961
* Returns an object containing the `@stream` arguments if a field should be
927
962
* streamed based on the experimental flag, stream directive present and
@@ -1897,36 +1932,22 @@ function executeStreamField(
1897
1932
exeContext,
1898
1933
} ) ;
1899
1934
if ( isPromise ( item ) ) {
1900
- const completedItems = item
1901
- . then ( ( resolved ) =>
1902
- completeValue (
1903
- exeContext ,
1904
- itemType ,
1905
- fieldNodes ,
1906
- info ,
1907
- itemPath ,
1908
- resolved ,
1909
- asyncPayloadRecord ,
1910
- ) ,
1911
- )
1912
- . then ( undefined , ( rawError ) => {
1913
- const error = locatedError ( rawError , fieldNodes , pathToArray ( itemPath ) ) ;
1914
- const handledError = handleFieldError (
1915
- error ,
1916
- itemType ,
1917
- asyncPayloadRecord . errors ,
1918
- ) ;
1919
- filterSubsequentPayloads ( exeContext , itemPath , asyncPayloadRecord ) ;
1920
- return handledError ;
1921
- } )
1922
- . then (
1923
- ( value ) => [ value ] ,
1924
- ( error ) => {
1925
- asyncPayloadRecord . errors . push ( error ) ;
1926
- filterSubsequentPayloads ( exeContext , path , asyncPayloadRecord ) ;
1927
- return null ;
1928
- } ,
1929
- ) ;
1935
+ const completedItems = completePromiseCatchingErrors (
1936
+ exeContext ,
1937
+ itemType ,
1938
+ fieldNodes ,
1939
+ info ,
1940
+ itemPath ,
1941
+ item ,
1942
+ asyncPayloadRecord ,
1943
+ ) . then (
1944
+ ( value ) => [ value ] ,
1945
+ ( error ) => {
1946
+ asyncPayloadRecord . errors . push ( error ) ;
1947
+ filterSubsequentPayloads ( exeContext , path , asyncPayloadRecord ) ;
1948
+ return null ;
1949
+ } ,
1950
+ ) ;
1930
1951
1931
1952
asyncPayloadRecord . addItems ( completedItems ) ;
1932
1953
return asyncPayloadRecord ;
0 commit comments