/** * Resolves the field on the given source object. In particular, this * figures out the object that the field returns using the resolve function, * then calls completeField to coerce scalars or execute the sub * selection set for objects. */ private static function resolveFieldOrError(ExecutionContext $exeContext, ObjectType $parentType, $source, $fieldASTs, FieldDefinition $fieldDef) { $fieldAST = $fieldASTs[0]; $fieldType = $fieldDef->getType(); $resolveFn = $fieldDef->resolve ?: [__CLASS__, 'defaultResolveFn']; // Build a JS object of arguments from the field.arguments AST, using the // variables scope to fulfill any variable references. // TODO: find a way to memoize, in case this field is within a Array type. $args = Values::getArgumentValues($fieldDef->args, $fieldAST->arguments, $exeContext->variables); try { $result = call_user_func($resolveFn, $source, $args, $exeContext->root, $fieldAST, $fieldType, $parentType, $exeContext->schema); } catch (\Exception $error) { throw new Error($error->getMessage(), [$fieldAST], $error->getTrace()); } return self::completeField($exeContext, $fieldType, $fieldASTs, $result); }