@@ -43,7 +43,6 @@ import {
4343 isListType ,
4444 isNonNullType ,
4545 isObjectType ,
46- isSemanticNonNullType ,
4746 isSemanticNullableType ,
4847} from '../type/definition' ;
4948import {
@@ -651,109 +650,85 @@ function completeValue(
651650 throw result ;
652651 }
653652
654- // If field type is NonNull, complete for inner type, and throw field error
655- // if result is null.
653+ let nonNull ;
654+ let semanticNull ;
655+ let nullableType ;
656656 if ( isNonNullType ( returnType ) ) {
657- const completed = completeValue (
658- exeContext ,
659- returnType . ofType ,
660- fieldNodes ,
661- info ,
662- path ,
663- result ,
664- ) ;
665- if ( completed === null ) {
666- throw new Error (
667- `Cannot return null for non-nullable field ${ info . parentType . name } .${ info . fieldName } .` ,
668- ) ;
669- }
670- return completed ;
657+ nonNull = true ;
658+ nullableType = returnType . ofType ;
659+ } else if ( isSemanticNullableType ( returnType ) ) {
660+ semanticNull = true ;
661+ nullableType = returnType . ofType ;
662+ } else {
663+ nullableType = returnType ;
671664 }
672665
673- // If field type is SemanticNonNull, complete for inner type, and throw field error
674- // if result is null and an error doesn't exist.
675- if ( isSemanticNonNullType ( returnType ) ) {
676- const completed = completeValue (
666+ let completed ;
667+ if ( result == null ) {
668+ // If result value is null or undefined then return null.
669+ completed = null ;
670+ } else if ( isListType ( nullableType ) ) {
671+ // If field type is List, complete each item in the list with the inner type
672+ completed = completeListValue (
677673 exeContext ,
678- returnType . ofType ,
674+ nullableType ,
679675 fieldNodes ,
680676 info ,
681677 path ,
682678 result ,
683679 ) ;
684- if ( completed === null ) {
685- throw new Error (
686- `Cannot return null for semantic-non-nullable field ${ info . parentType . name } .${ info . fieldName } .` ,
687- ) ;
688- }
689- return completed ;
690- }
691-
692- // If field type is SemanticNullable, complete for inner type
693- if ( isSemanticNullableType ( returnType ) ) {
694- return completeValue (
680+ } else if ( isLeafType ( nullableType ) ) {
681+ // If field type is a leaf type, Scalar or Enum, serialize to a valid value,
682+ // returning null if serialization is not possible.
683+ completed = completeLeafValue ( nullableType , result ) ;
684+ } else if ( isAbstractType ( nullableType ) ) {
685+ // If field type is an abstract type, Interface or Union, determine the
686+ // runtime Object type and complete for that type.
687+ completed = completeAbstractValue (
695688 exeContext ,
696- returnType . ofType ,
689+ nullableType ,
697690 fieldNodes ,
698691 info ,
699692 path ,
700693 result ,
701694 ) ;
702- }
703-
704- // If result value is null or undefined then return null.
705- if ( result == null ) {
706- return null ;
707- }
708-
709- // If field type is List, complete each item in the list with the inner type
710- if ( isListType ( returnType ) ) {
711- return completeListValue (
695+ } else if ( isObjectType ( nullableType ) ) {
696+ // If field type is Object, execute and complete all sub-selections.
697+ completed = completeObjectValue (
712698 exeContext ,
713- returnType ,
699+ nullableType ,
714700 fieldNodes ,
715701 info ,
716702 path ,
717703 result ,
718704 ) ;
705+ } else {
706+ /* c8 ignore next 6 */
707+ // Not reachable, all possible output types have been considered.
708+ invariant (
709+ false ,
710+ 'Cannot complete value of unexpected output type: ' +
711+ inspect ( nullableType ) ,
712+ ) ;
719713 }
720714
721- // If field type is a leaf type, Scalar or Enum, serialize to a valid value,
722- // returning null if serialization is not possible.
723- if ( isLeafType ( returnType ) ) {
724- return completeLeafValue ( returnType , result ) ;
725- }
726-
727- // If field type is an abstract type, Interface or Union, determine the
728- // runtime Object type and complete for that type.
729- if ( isAbstractType ( returnType ) ) {
730- return completeAbstractValue (
731- exeContext ,
732- returnType ,
733- fieldNodes ,
734- info ,
735- path ,
736- result ,
715+ if ( nonNull && completed === null ) {
716+ throw new Error (
717+ `Cannot return null for non-nullable field ${ info . parentType . name } .${ info . fieldName } .` ,
737718 ) ;
738719 }
739720
740- // If field type is Object, execute and complete all sub-selections.
741- if ( isObjectType ( returnType ) ) {
742- return completeObjectValue (
743- exeContext ,
744- returnType ,
745- fieldNodes ,
746- info ,
747- path ,
748- result ,
721+ if (
722+ exeContext . schema . usingSemanticNullability &&
723+ ! semanticNull &&
724+ completed === null
725+ ) {
726+ throw new Error (
727+ `Cannot return null for semantic-non-nullable field ${ info . parentType . name } .${ info . fieldName } .` ,
749728 ) ;
750729 }
751- /* c8 ignore next 6 */
752- // Not reachable, all possible output types have been considered.
753- invariant (
754- false ,
755- 'Cannot complete value of unexpected output type: ' + inspect ( returnType ) ,
756- ) ;
730+
731+ return completed ;
757732}
758733
759734/**
0 commit comments