From 4227404aeee18f1d781e71ada32b2e15866c3685 Mon Sep 17 00:00:00 2001 From: Vladimir Razuvaev Date: Tue, 7 Aug 2018 23:25:01 +0700 Subject: [PATCH] Added test for useful error when returning invalid value from resolveType --- src/Executor/Executor.php | 11 ++++--- tests/Executor/AbstractTest.php | 55 +++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/Executor/Executor.php b/src/Executor/Executor.php index 26ecd09..4251554 100644 --- a/src/Executor/Executor.php +++ b/src/Executor/Executor.php @@ -1400,15 +1400,16 @@ class Executor if (! $runtimeType instanceof ObjectType) { throw new InvariantViolation( sprintf( - 'Abstract type %1$s must resolve to an Object type at ' . - 'runtime for field %s.%s with value "%s", received "%s".' . - 'Either the %1$s type should provide a "resolveType" ' . - 'function or each possible types should provide an "isTypeOf" function.', + 'Abstract type %s must resolve to an Object type at ' . + 'runtime for field %s.%s with value "%s", received "%s". ' . + 'Either the %s type should provide a "resolveType" ' . + 'function or each possible type should provide an "isTypeOf" function.', $returnType, $info->parentType, $info->fieldName, Utils::printSafe($result), - Utils::printSafe($runtimeType) + Utils::printSafe($runtimeType), + $returnType ) ); } diff --git a/tests/Executor/AbstractTest.php b/tests/Executor/AbstractTest.php index 057b6a3..7236746 100644 --- a/tests/Executor/AbstractTest.php +++ b/tests/Executor/AbstractTest.php @@ -357,6 +357,61 @@ class AbstractTest extends TestCase $this->assertArraySubset($expected, $result); } + /** + * @it returning invalid value from resolveType yields useful error + */ + public function testReturningInvalidValueFromResolveTypeYieldsUsefulError() + { + $fooInterface = new InterfaceType([ + 'name' => 'FooInterface', + 'fields' => ['bar' => ['type' => Type::string()]], + 'resolveType' => function () { + return []; + }, + ]); + + $fooObject = new ObjectType([ + 'name' => 'FooObject', + 'fields' => ['bar' => ['type' => Type::string()]], + 'interfaces' => [$fooInterface], + ]); + + $schema = new Schema([ + 'query' => new ObjectType([ + 'name' => 'Query', + 'fields' => [ + 'foo' => [ + 'type' => $fooInterface, + 'resolve' => function () { + return 'dummy'; + }, + ], + ], + ]), + 'types' => [$fooObject], + ]); + + $result = GraphQL::executeQuery($schema, '{ foo { bar } }'); + + $expected = [ + 'data' => ['foo' => null], + 'errors' => [ + [ + 'message' => 'Internal server error', + 'debugMessage' => + 'Abstract type FooInterface must resolve to an Object type at ' . + 'runtime for field Query.foo with value "dummy", received "[]". ' . + 'Either the FooInterface type should provide a "resolveType" ' . + 'function or each possible type should provide an "isTypeOf" function.', + 'locations' => [['line' => 1, 'column' => 3]], + 'path' => ['foo'], + 'category' => 'internal', + ], + ], + ]; + $this->assertEquals($expected, $result->toArray(true)); + } + /** * @it resolveType allows resolving with type name */