markhuot / craftql

A drop-in GraphQL server for Craft CMS
Other
319 stars 53 forks source link

Query for an Entries field inside of a SuperTable fails unexpectedly (permissions) #97

Closed khalwat closed 6 years ago

khalwat commented 6 years ago

So this is clearly a PEBCAK problem, in that I had the wrong permissions (more below) but it took longer than I'd expected to figure out what was going wrong due to the error (or lack thereof) that was returned.

I have the following query:

    query getQuestion($questionId: Int!)
    {
      entries(section: [questions], id: [$questionId]) {
    ... on Questions {
      title
      question
      questionAnswers {
        answer
        nextQuestion {
          id
        }
        insight {
          id
        }
      }
    }
  }
}

In this case, questionAnswers is a SuperTable field, with both nextQuestion and insight being Entries fields that the user can pick an entry from in the AdminCP.

This query works fine in GraphiQL:

google chromescreensnapz1191

However on the frontend when queried via graphql-request I get a 500 error from the server:

google chromescreensnapz1190

Which was very strange, because it worked fine with the nextQuestion Entries field. The stack trace was also somewhat unhelpful in pointing me in the right direction:

2018-05-23 09:07:12 [192.168.10.1][-][-][error][GraphQL\Error\InvariantViolation] GraphQL\Error\InvariantViolation: Abstract type EntryInterface must resolve to an Object type at runtime for field QuestionAnswersSuperTableBlockType.insight with value "instance of craft\elements\Entry", received "null". in /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php:1124
Stack trace:
#0 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(1093): GraphQL\Executor\Executor->ensureValidRuntimeType('Insights', Object(GraphQL\Type\Definition\InterfaceType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), '...')
#1 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(961): GraphQL\Executor\Executor->completeAbstractValue(Object(GraphQL\Type\Definition\InterfaceType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#2 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(845): GraphQL\Executor\Executor->completeValue(Object(GraphQL\Type\Definition\InterfaceType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#3 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(799): GraphQL\Executor\Executor->completeValueWithLocatedError(Object(GraphQL\Type\Definition\InterfaceType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#4 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(1175): GraphQL\Executor\Executor->completeValueCatchingError(Object(GraphQL\Type\Definition\InterfaceType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, Object(craft\elements\Entry))
#5 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(937): GraphQL\Executor\Executor->completeListValue(Object(GraphQL\Type\Definition\ListOfType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#6 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(845): GraphQL\Executor\Executor->completeValue(Object(GraphQL\Type\Definition\ListOfType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#7 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(799): GraphQL\Executor\Executor->completeValueWithLocatedError(Object(GraphQL\Type\Definition\ListOfType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#8 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(721): GraphQL\Executor\Executor->completeValueCatchingError(Object(GraphQL\Type\Definition\ListOfType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, Object(craft\elements\db\EntryQuery))
#9 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(442): GraphQL\Executor\Executor->resolveField(Object(GraphQL\Type\Definition\ObjectType), Object(verbb\supertable\elements\SuperTableBlockElement), Object(ArrayObject), Array)
#10 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(1305): GraphQL\Executor\Executor->executeFields(Object(GraphQL\Type\Definition\ObjectType), Object(verbb\supertable\elements\SuperTableBlockElement), Array, Object(ArrayObject))
#11 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(1250): GraphQL\Executor\Executor->collectAndExecuteSubfields(Object(GraphQL\Type\Definition\ObjectType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#12 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(966): GraphQL\Executor\Executor->completeObjectValue(Object(GraphQL\Type\Definition\ObjectType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#13 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(845): GraphQL\Executor\Executor->completeValue(Object(GraphQL\Type\Definition\ObjectType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#14 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(799): GraphQL\Executor\Executor->completeValueWithLocatedError(Object(GraphQL\Type\Definition\ObjectType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#15 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(1175): GraphQL\Executor\Executor->completeValueCatchingError(Object(GraphQL\Type\Definition\ObjectType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, Object(verbb\supertable\elements\SuperTableBlockElement))
#16 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(937): GraphQL\Executor\Executor->completeListValue(Object(GraphQL\Type\Definition\ListOfType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#17 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(845): GraphQL\Executor\Executor->completeValue(Object(GraphQL\Type\Definition\ListOfType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#18 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(799): GraphQL\Executor\Executor->completeValueWithLocatedError(Object(GraphQL\Type\Definition\ListOfType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#19 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(721): GraphQL\Executor\Executor->completeValueCatchingError(Object(GraphQL\Type\Definition\ListOfType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, Array)
#20 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(442): GraphQL\Executor\Executor->resolveField(Object(GraphQL\Type\Definition\ObjectType), Object(craft\elements\Entry), Object(ArrayObject), Array)
#21 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(1305): GraphQL\Executor\Executor->executeFields(Object(GraphQL\Type\Definition\ObjectType), Object(craft\elements\Entry), Array, Object(ArrayObject))
#22 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(1250): GraphQL\Executor\Executor->collectAndExecuteSubfields(Object(GraphQL\Type\Definition\ObjectType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#23 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(1098): GraphQL\Executor\Executor->completeObjectValue(Object(GraphQL\Type\Definition\ObjectType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#24 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(961): GraphQL\Executor\Executor->completeAbstractValue(Object(GraphQL\Type\Definition\InterfaceType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#25 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(845): GraphQL\Executor\Executor->completeValue(Object(GraphQL\Type\Definition\InterfaceType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#26 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(799): GraphQL\Executor\Executor->completeValueWithLocatedError(Object(GraphQL\Type\Definition\InterfaceType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#27 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(1175): GraphQL\Executor\Executor->completeValueCatchingError(Object(GraphQL\Type\Definition\InterfaceType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, Object(craft\elements\Entry))
#28 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(937): GraphQL\Executor\Executor->completeListValue(Object(GraphQL\Type\Definition\ListOfType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#29 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(845): GraphQL\Executor\Executor->completeValue(Object(GraphQL\Type\Definition\ListOfType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#30 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(799): GraphQL\Executor\Executor->completeValueWithLocatedError(Object(GraphQL\Type\Definition\ListOfType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, '...')
#31 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(721): GraphQL\Executor\Executor->completeValueCatchingError(Object(GraphQL\Type\Definition\ListOfType), Object(ArrayObject), Object(GraphQL\Type\Definition\ResolveInfo), Array, Object(craft\elements\db\EntryQuery))
#32 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(442): GraphQL\Executor\Executor->resolveField(Object(GraphQL\Type\Definition\ObjectType), NULL, Object(ArrayObject), Array)
#33 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(324): GraphQL\Executor\Executor->executeFields(Object(GraphQL\Type\Definition\ObjectType), NULL, Array, Object(ArrayObject))
#34 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(287): GraphQL\Executor\Executor->executeOperation(Object(GraphQL\Language\AST\OperationDefinitionNode), NULL)
#35 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Promise/Adapter/SyncPromiseAdapter.php(59): GraphQL\Executor\Executor->GraphQL\Executor\{closure}(Array, Array)
#36 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(288): GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter->create(Object(Closure))
#37 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/Executor/Executor.php(151): GraphQL\Executor\Executor->doExecute()
#38 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/GraphQL.php(155): GraphQL\Executor\Executor::promiseToExecute(Object(GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter), Object(GraphQL\Type\Schema), Object(GraphQL\Language\AST\DocumentNode), NULL, NULL, Array, NULL, NULL)
#39 /home/vagrant/sites/museumofdata/vendor/webonyx/graphql-php/src/GraphQL.php(86): GraphQL\GraphQL::promiseToExecute(Object(GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter), Object(GraphQL\Type\Schema), '\n    query getQ...', NULL, NULL, Array, NULL, NULL, NULL)
#40 /home/vagrant/sites/museumofdata/vendor/markhuot/craftql/src/Services/GraphQLService.php(107): GraphQL\GraphQL::executeQuery(Object(GraphQL\Type\Schema), '\n    query getQ...', NULL, NULL, Array)
#41 /home/vagrant/sites/museumofdata/vendor/markhuot/craftql/src/Controllers/ApiController.php(120): markhuot\CraftQL\Services\GraphQLService->execute(Object(GraphQL\Type\Schema), '\n    query getQ...', Array)
#42 [internal function]: markhuot\CraftQL\Controllers\ApiController->actionIndex()
#43 /home/vagrant/sites/museumofdata/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#44 /home/vagrant/sites/museumofdata/vendor/yiisoft/yii2/base/Controller.php(157): yii\base\InlineAction->runWithParams(Array)
#45 /home/vagrant/sites/museumofdata/vendor/craftcms/cms/src/web/Controller.php(76): yii\base\Controller->runAction('index', Array)
#46 /home/vagrant/sites/museumofdata/vendor/yiisoft/yii2/base/Module.php(528): craft\web\Controller->runAction('index', Array)
#47 /home/vagrant/sites/museumofdata/vendor/craftcms/cms/src/web/Application.php(273): yii\base\Module->runAction('craftql/api/ind...', Array)
#48 /home/vagrant/sites/museumofdata/vendor/yiisoft/yii2/web/Application.php(103): craft\web\Application->runAction('craftql/api/ind...', Array)
#49 /home/vagrant/sites/museumofdata/vendor/craftcms/cms/src/web/Application.php(262): yii\web\Application->handleRequest(Object(craft\web\Request))
#50 /home/vagrant/sites/museumofdata/vendor/yiisoft/yii2/base/Application.php(386): craft\web\Application->handleRequest(Object(craft\web\Request))
#51 /home/vagrant/sites/museumofdata/web/index.php(21): yii\base\Application->run()
#52 {main}

The issue only happened if an actual entry was selected in the insight Entries field. It ends up just being that the token permissions were wrong:

google chromescreensnapz1189

...but perhaps some better error reporting is in order here?

Incidentally, if I click on the You can explore your API with the permissions of this token in GraphiQL. link from the Token Scopes page, I just get a screen that says Loading and nothing ever loads, so I can't test the token permissions via GraphiQL that way.

markhuot commented 6 years ago

FYI, the "You can explore…" / token browse link is fixed on dev-master. I'm working on error reporting and overall better management of querying separately. Will leave this open until that merges.

timkelty commented 6 years ago

Just ran into the same problem @khalwat had (entries field in a matrix w/o permissions). A better error were would be great :)

markhuot commented 6 years ago

FYI, I updated the Entries field type to match all the other entries fields across CraftQL. The upside of this is that if you ask an entries field for the related entries you'll only get back entries you have access too. The downside is that there's no error any more, it just silently removes any entries you don't have access to…

This is on dev-master for your review.

markhuot commented 6 years ago

1.1.0 was released on 2018-06-27 and includes this fix.