@@ -415,11 +415,16 @@ private static function resolveField(ExecutionContext $exeContext, ObjectType $p
415415 if ($ mapFn ) {
416416 try {
417417 $ mapped = call_user_func ($ mapFn , $ sourceValueList , $ args , $ info );
418+ $ validType = is_array ($ mapped ) || ($ mapped instanceof \Traversable && $ mapped instanceof \Countable);
419+ $ mappedCount = count ($ mapped );
420+ $ sourceCount = count ($ sourceValueList );
418421
419422 Utils::invariant (
420- is_array ($ mapped ) && count ($ mapped ) === count ($ sourceValueList ),
421- "Function `map` of $ parentType. $ fieldName is expected to return array " .
422- "with exact same number of items as list being mapped (first argument of `map`) "
423+ $ validType && count ($ mapped ) === count ($ sourceValueList ),
424+ "Function `map` of $ parentType. $ fieldName is expected to return array or " .
425+ "countable traversable with exact same number of items as list being mapped. " .
426+ "Got '%s' with count ' $ mappedCount' against ' $ sourceCount' expected. " ,
427+ Utils::getVariableType ($ mapped )
423428 );
424429
425430 } catch (\Exception $ error ) {
@@ -682,7 +687,8 @@ private static function completeValue(ExecutionContext $exeContext, Type $return
682687
683688 // Collect sub-fields to execute to complete this value.
684689 $ subFieldASTs = self ::collectSubFields ($ exeContext , $ objectType , $ fieldASTs );
685- return self ::executeFields ($ exeContext , $ objectType , [$ result ], $ subFieldASTs )[0 ];
690+ $ executed = self ::executeFields ($ exeContext , $ objectType , [$ result ], $ subFieldASTs );
691+ return isset ($ executed [0 ]) ? $ executed [0 ] : null ;
686692 }
687693
688694 /**
0 commit comments