src/Executor/ReferenceExecutor.php
private function completeValueCatchingError(
        Type $returnType,
        $fieldNodes,
        ResolveInfo $info,
        $path,
        $result
    ) {
        $exeContext = $this->exeContext;
        // If the field type is non-nullable, then it is resolved without any
        // protection from errors.
        if ($returnType instanceof NonNull) {
            return $this->completeValueWithLocatedError(
                $returnType,
                $fieldNodes,
                $info,
                $path,
                $result
            );
        }
        // Otherwise, error protection is applied, logging the error and resolving
        // a null value for this field if one is encountered.
        try {
            $completed = $this->completeValueWithLocatedError(
                $returnType,
                $fieldNodes,
                $info,
                $path,
                $result
            );
            $promise   = $this->getPromise($completed);
            if ($promise) {
                return $promise->then(
                    null,
                    function ($error) use ($exeContext) {
                        $exeContext->addError($error);

                        return $this->exeContext->promises->createFulfilled(null);
                    }
                );
            }

            return $completed;
        } catch (Error $err) {
            // If `completeValueWithLocatedError` returned abruptly (threw an error), log the error
            // and return null.
            $exeContext->addError($err);

            return null;
        }
    }
private function completeValueCatchingError(
        Type $returnType,
        $fieldNodes,
        ResolveInfo $info,
        $path,
        $result
    ) {
        $exeContext = $this->exeContext;
        // If the field type is non-nullable, then it is resolved without any
        // protection from errors.
        if ($returnType instanceof NonNull) {
            return $this->completeValueWithLocatedError(
                $returnType,
                $fieldNodes,
                $info,
                $path,
                $result
            );
        }
        // Otherwise, error protection is applied, logging the error and resolving
        // a null value for this field if one is encountered.
        try {
            $completed = $this->completeValueWithLocatedError(
                $returnType,
                $fieldNodes,
                $info,
                $path,
                $result
            );
            $promise   = $this->getPromise($completed);
            if ($promise) {
                return $promise->then(
                    null,
                    function ($error) use ($exeContext) {
                        $exeContext->addError($error);

                        return $this->exeContext->promises->createFulfilled(null);
                    }
                );
            }

            return $completed;
        } catch (Error $err) {
            // If `completeValueWithLocatedError` returned abruptly (threw an error), log the error
            // and return null.
            $exeContext->addError($err);

            return null;
        }
    }
This is a small wrapper around completeValue which detects and logs errors
in the execution context.

@param FieldNode[] $fieldNodes
@param string[]    $path
@param mixed       $result

@return mixed[]|Promise|null