mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-29 00:25:17 +03:00
Minor executor refactoring related to handling "resolve" errors
This commit is contained in:
parent
83f42825f8
commit
965c3ff743
@ -324,7 +324,13 @@ class Executor
|
|||||||
*/
|
*/
|
||||||
private static function doesFragmentConditionMatch(ExecutionContext $exeContext,/* FragmentDefinition | InlineFragment*/ $fragment, ObjectType $type)
|
private static function doesFragmentConditionMatch(ExecutionContext $exeContext,/* FragmentDefinition | InlineFragment*/ $fragment, ObjectType $type)
|
||||||
{
|
{
|
||||||
$conditionalType = Utils\TypeInfo::typeFromAST($exeContext->schema, $fragment->typeCondition);
|
$typeConditionAST = $fragment->typeCondition;
|
||||||
|
|
||||||
|
if (!$typeConditionAST) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$conditionalType = Utils\TypeInfo::typeFromAST($exeContext->schema, $typeConditionAST);
|
||||||
if ($conditionalType === $type) {
|
if ($conditionalType === $type) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -394,22 +400,9 @@ class Executor
|
|||||||
'variableValues' => $exeContext->variableValues,
|
'variableValues' => $exeContext->variableValues,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// If an error occurs while calling the field `resolve` function, ensure that
|
// Get the resolve function, regardless of if its result is normal
|
||||||
// it is wrapped as a GraphQLError with locations. Log this error and return
|
// or abrupt (error).
|
||||||
// null if allowed, otherwise throw the error so the parent field can handle
|
$result = self::resolveOrError($resolveFn, $source, $args, $info);
|
||||||
// it.
|
|
||||||
try {
|
|
||||||
$result = call_user_func($resolveFn, $source, $args, $info);
|
|
||||||
} catch (\Exception $error) {
|
|
||||||
$reportedError = Error::createLocatedError($error, $fieldASTs);
|
|
||||||
|
|
||||||
if ($returnType instanceof NonNull) {
|
|
||||||
throw $reportedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
$exeContext->addError($reportedError);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self::completeValueCatchingError(
|
return self::completeValueCatchingError(
|
||||||
$exeContext,
|
$exeContext,
|
||||||
@ -420,6 +413,16 @@ class Executor
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Isolates the "ReturnOrAbrupt" behavior to not de-opt the `resolveField`
|
||||||
|
// function. Returns the result of resolveFn or the abrupt-return Error object.
|
||||||
|
private static function resolveOrError($resolveFn, $source, $args, $info)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return call_user_func($resolveFn, $source, $args, $info);
|
||||||
|
} catch (\Exception $error) {
|
||||||
|
return $error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static function completeValueCatchingError(
|
public static function completeValueCatchingError(
|
||||||
ExecutionContext $exeContext,
|
ExecutionContext $exeContext,
|
||||||
@ -440,6 +443,8 @@ class Executor
|
|||||||
try {
|
try {
|
||||||
return self::completeValue($exeContext, $returnType, $fieldASTs, $info, $result);
|
return self::completeValue($exeContext, $returnType, $fieldASTs, $info, $result);
|
||||||
} catch (Error $err) {
|
} catch (Error $err) {
|
||||||
|
// If `completeValue` returned abruptly (threw an error), log the error
|
||||||
|
// and return null.
|
||||||
$exeContext->addError($err);
|
$exeContext->addError($err);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -465,6 +470,10 @@ class Executor
|
|||||||
*/
|
*/
|
||||||
private static function completeValue(ExecutionContext $exeContext, Type $returnType,/* Array<Field> */ $fieldASTs, ResolveInfo $info, &$result)
|
private static function completeValue(ExecutionContext $exeContext, Type $returnType,/* Array<Field> */ $fieldASTs, ResolveInfo $info, &$result)
|
||||||
{
|
{
|
||||||
|
if ($result instanceof \Exception) {
|
||||||
|
throw Error::createLocatedError($result, $fieldASTs);
|
||||||
|
}
|
||||||
|
|
||||||
// If field type is NonNull, complete for inner type, and throw field error
|
// If field type is NonNull, complete for inner type, and throw field error
|
||||||
// if result is null.
|
// if result is null.
|
||||||
if ($returnType instanceof NonNull) {
|
if ($returnType instanceof NonNull) {
|
||||||
@ -514,29 +523,29 @@ class Executor
|
|||||||
|
|
||||||
// Field type must be Object, Interface or Union and expect sub-selections.
|
// Field type must be Object, Interface or Union and expect sub-selections.
|
||||||
if ($returnType instanceof ObjectType) {
|
if ($returnType instanceof ObjectType) {
|
||||||
$objectType = $returnType;
|
$runtimeType = $returnType;
|
||||||
} else if ($returnType instanceof AbstractType) {
|
} else if ($returnType instanceof AbstractType) {
|
||||||
$objectType = $returnType->getObjectType($result, $info);
|
$runtimeType = $returnType->getObjectType($result, $info);
|
||||||
|
|
||||||
if ($objectType && !$returnType->isPossibleType($objectType)) {
|
if ($runtimeType && !$returnType->isPossibleType($runtimeType)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Runtime Object type \"$objectType\" is not a possible type for \"$returnType\"."
|
"Runtime Object type \"$runtimeType\" is not a possible type for \"$returnType\"."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$objectType = null;
|
$runtimeType = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$objectType) {
|
if (!$runtimeType) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is an isTypeOf predicate function, call it with the
|
// If there is an isTypeOf predicate function, call it with the
|
||||||
// current result. If isTypeOf returns false, then raise an error rather
|
// current result. If isTypeOf returns false, then raise an error rather
|
||||||
// than continuing execution.
|
// than continuing execution.
|
||||||
if (false === $objectType->isTypeOf($result, $info)) {
|
if (false === $runtimeType->isTypeOf($result, $info)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Expected value of type $objectType but got: $result.",
|
"Expected value of type $runtimeType but got: $result.",
|
||||||
$fieldASTs
|
$fieldASTs
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -549,7 +558,7 @@ class Executor
|
|||||||
if ($selectionSet) {
|
if ($selectionSet) {
|
||||||
$subFieldASTs = self::collectFields(
|
$subFieldASTs = self::collectFields(
|
||||||
$exeContext,
|
$exeContext,
|
||||||
$objectType,
|
$runtimeType,
|
||||||
$selectionSet,
|
$selectionSet,
|
||||||
$subFieldASTs,
|
$subFieldASTs,
|
||||||
$visitedFragmentNames
|
$visitedFragmentNames
|
||||||
@ -557,7 +566,7 @@ class Executor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::executeFields($exeContext, $objectType, $result, $subFieldASTs);
|
return self::executeFields($exeContext, $runtimeType, $result, $subFieldASTs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user