Skip to content

Commit e40e016

Browse files
committed
avoid additional stack for completing non-nullable types
1 parent 3610786 commit e40e016

File tree

1 file changed

+20
-27
lines changed

1 file changed

+20
-27
lines changed

src/execution/execute.ts

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import type {
3131
GraphQLFieldResolver,
3232
GraphQLLeafType,
3333
GraphQLList,
34+
GraphQLNullableOutputType,
3435
GraphQLObjectType,
3536
GraphQLOutputType,
3637
GraphQLResolveInfo,
@@ -822,36 +823,28 @@ function completeValue(
822823
throw result;
823824
}
824825

825-
// If field type is NonNull, complete for inner type, and throw field error
826-
// if result is null.
826+
let nullableType: GraphQLNullableOutputType;
827827
if (isNonNullType(returnType)) {
828-
const completed = completeValue(
829-
exeContext,
830-
returnType.ofType,
831-
fieldGroup,
832-
info,
833-
path,
834-
result,
835-
incrementalDataRecord,
836-
);
837-
if (completed === null) {
828+
// If result value is null or undefined then throw an error.
829+
if (result == null) {
838830
throw new Error(
839831
`Cannot return null for non-nullable field ${info.parentType.name}.${info.fieldName}.`,
840832
);
841833
}
842-
return completed;
843-
}
844-
845-
// If result value is null or undefined then return null.
846-
if (result == null) {
847-
return null;
834+
nullableType = returnType.ofType;
835+
} else {
836+
// If result value is null or undefined then return null.
837+
if (result == null) {
838+
return null;
839+
}
840+
nullableType = returnType;
848841
}
849842

850843
// If field type is List, complete each item in the list with the inner type
851-
if (isListType(returnType)) {
844+
if (isListType(nullableType)) {
852845
return completeListValue(
853846
exeContext,
854-
returnType,
847+
nullableType,
855848
fieldGroup,
856849
info,
857850
path,
@@ -862,16 +855,16 @@ function completeValue(
862855

863856
// If field type is a leaf type, Scalar or Enum, serialize to a valid value,
864857
// returning null if serialization is not possible.
865-
if (isLeafType(returnType)) {
866-
return completeLeafValue(returnType, result);
858+
if (isLeafType(nullableType)) {
859+
return completeLeafValue(nullableType, result);
867860
}
868861

869862
// If field type is an abstract type, Interface or Union, determine the
870863
// runtime Object type and complete for that type.
871-
if (isAbstractType(returnType)) {
864+
if (isAbstractType(nullableType)) {
872865
return completeAbstractValue(
873866
exeContext,
874-
returnType,
867+
nullableType,
875868
fieldGroup,
876869
info,
877870
path,
@@ -881,10 +874,10 @@ function completeValue(
881874
}
882875

883876
// If field type is Object, execute and complete all sub-selections.
884-
if (isObjectType(returnType)) {
877+
if (isObjectType(nullableType)) {
885878
return completeObjectValue(
886879
exeContext,
887-
returnType,
880+
nullableType,
888881
fieldGroup,
889882
info,
890883
path,
@@ -896,7 +889,7 @@ function completeValue(
896889
// Not reachable, all possible output types have been considered.
897890
invariant(
898891
false,
899-
'Cannot complete value of unexpected output type: ' + inspect(returnType),
892+
'Cannot complete value of unexpected output type: ' + inspect(nullableType),
900893
);
901894
}
902895

0 commit comments

Comments
 (0)