verbb / navigation

A Craft CMS plugin to create navigation menus for your site.
Other
90 stars 23 forks source link

Error running sourceNodes #316

Closed zjr closed 2 years ago

zjr commented 2 years ago

Describe the bug

Hello again! Sorry to bug you but I seem to have encountered another issue in the Navigation / Gatsby Plugin / gatsby-source-craft triangle.

This problem occurs during Gatsby's sourceNodes lifecycle after updating a something in Navigation. I do have a bit of background for this one.

Here's the error that occurs on the Gatsby end:

info Craft config version has not changed since last sourcing. Checking for content changes since "2022-09-25
18:56:30".

 ERROR #11321  PLUGIN

"gatsby-source-craft" threw an error while running the sourceNodes lifecycle:

Cannot read properties of null (reading 'map')

  541 |         // Create the sourcing node events
  542 |         const nodeEvents = [
> 543 |             ...updatedNodes.map(entry => {
      |                             ^
  544 |                 return {
  545 |                     eventName: 'UPDATE',
  546 |                     remoteTypeName: entry.nodeType,

File: node_modules/gatsby-source-craft/gatsby-node.js:543:29

  TypeError: Cannot read properties of null (reading 'map')

  - gatsby-node.js:543 Object.exports.sourceNodes
    [heparks-client]/[gatsby-source-craft]/gatsby-node.js:543:29

  - task_queues:96 processTicksAndRejections
    node:internal/process/task_queues:96:5

  - api-runner-node.js:487 runAPI
    [heparks-client]/[gatsby]/src/utils/api-runner-node.js:487:16

warn The gatsby-source-craft plugin has generated no Gatsby nodes. Do you need it? This could also suggest the plugin
is misconfigured.

NOTE: I found that this error occurs because updatedNodes is null, so, trying to map it will cause a TypeError. it's null because the query it's trying to get data from actually returns an error, but, for some reason, gatsby-source-craft decides not to check for or throw any errors from the GraphQL query it executes here.

Here is the actual result of the query it's running:

{
  "errors": [
    {
      "debugMessage": "SQLSTATE[22P02]: Invalid text representation: 7 ERROR:  invalid input syntax for type integer: \"\"\nCONTEXT:  unnamed portal parameter $4 = ''",
      "message": "Internal server error",
      "extensions": {
        "category": "internal"
      },
      "trace": [
        {
          "file": "/var/www/html/vendor/yiisoft/yii2/db/Command.php",
          "line": 1302,
          "call": "PDOStatement::execute()"
        },
        {
          "file": "/var/www/html/vendor/yiisoft/yii2/db/Command.php",
          "line": 1168,
          "call": "yii\\db\\Command::internalExecute('SELECT \"e\".\"id\", \"e\".\"type\", \"es\".\"siteId\"\nFROM \"elements\" \"e\"\nINNER JOIN \"elements_sites\" \"es\" ON (\"e\".\"id\" = \"es\".\"elementId\") AND (\"es\".\"siteId\"=1)\nWHERE (\"e\".\"dateDeleted\" IS NULL) AND (\"e\".\"type\"<>\\'craft\\elements\\MatrixBlock\\') AND ((\"e\".\"dateUpdated\" > \\'2022-09-25 18:56:30\\') OR (\"e\".\"id\" IN (\\'\\', 317))) AND (\"e\".\"revisionId\" IS NULL) AND (\"e\".\"draftId\" IS NULL)')"
        },
        {
          "file": "/var/www/html/vendor/yiisoft/yii2/db/Command.php",
          "line": 410,
          "call": "yii\\db\\Command::queryInternal('fetchAll', null)"
        },
        {
          "file": "/var/www/html/vendor/yiisoft/yii2/db/Query.php",
          "line": 249,
          "call": "yii\\db\\Command::queryAll()"
        },
        {
          "file": "/var/www/html/vendor/craftcms/cms/src/db/Query.php",
          "line": 247,
          "call": "yii\\db\\Query::all(null)"
        },
        {
          "file": "/var/www/html/vendor/craftcms/gatsby-helper/src/services/Deltas.php",
          "line": 119,
          "call": "craft\\db\\Query::all()"
        },
        {
          "file": "/var/www/html/vendor/craftcms/gatsby-helper/src/gql/resolvers/UpdatedNode.php",
          "line": 41,
          "call": "craft\\gatsbyhelper\\services\\Deltas::getUpdatedNodesSinceTimeStamp('2022-09-25 18:56:30', array(1))"
        },
        {
          "file": "/var/www/html/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 623,
          "call": "craft\\gatsbyhelper\\gql\\resolvers\\UpdatedNode::resolve(null, array(2), array(2), instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "/var/www/html/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 550,
          "call": "GraphQL\\Executor\\ReferenceExecutor::resolveFieldValueOrError(instance of GraphQL\\Type\\Definition\\FieldDefinition, instance of GraphQL\\Language\\AST\\FieldNode, 'craft\\gatsbyhelper\\gql\\resolvers\\UpdatedNode::resolve', null, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "/var/www/html/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 1195,
          "call": "GraphQL\\Executor\\ReferenceExecutor::resolveField(GraphQLType: Query, null, instance of ArrayObject(1), array(1))"
        },
        {
          "file": "/var/www/html/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 264,
          "call": "GraphQL\\Executor\\ReferenceExecutor::executeFields(GraphQLType: Query, null, array(0), instance of ArrayObject(2))"
        },
        {
          "file": "/var/www/html/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
          "line": 215,
          "call": "GraphQL\\Executor\\ReferenceExecutor::executeOperation(instance of GraphQL\\Language\\AST\\OperationDefinitionNode, null)"
        },
        {
          "file": "/var/www/html/vendor/webonyx/graphql-php/src/Executor/Executor.php",
          "line": 156,
          "call": "GraphQL\\Executor\\ReferenceExecutor::doExecute()"
        },
        {
          "file": "/var/www/html/vendor/webonyx/graphql-php/src/GraphQL.php",
          "line": 162,
          "call": "GraphQL\\Executor\\Executor::promiseToExecute(instance of GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter, instance of GraphQL\\Type\\Schema, instance of GraphQL\\Language\\AST\\DocumentNode, null, array(2), array(2), 'nodeChanges', null)"
        },
        {
          "file": "/var/www/html/vendor/webonyx/graphql-php/src/GraphQL.php",
          "line": 94,
          "call": "GraphQL\\GraphQL::promiseToExecute(instance of GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter, instance of GraphQL\\Type\\Schema, 'query nodeChanges($since: String!, $site: [String]) {\n                nodesUpdatedSince (since: $since site: $site) { nodeId nodeType siteId}\n                nodesDeletedSince (since: $since) { nodeId nodeType siteId}\n            }', null, array(2), array(2), 'nodeChanges', null, array(26))"
        },
        {
          "file": "/var/www/html/vendor/craftcms/cms/src/services/Gql.php",
          "line": 513,
          "call": "GraphQL\\GraphQL::executeQuery(instance of GraphQL\\Type\\Schema, 'query nodeChanges($since: String!, $site: [String]) {\n                nodesUpdatedSince (since: $since site: $site) { nodeId nodeType siteId}\n                nodesDeletedSince (since: $since) { nodeId nodeType siteId}\n            }', null, array(2), array(2), 'nodeChanges', null, array(26))"
        },
        {
          "file": "/var/www/html/vendor/craftcms/cms/src/controllers/GraphqlController.php",
          "line": 177,
          "call": "craft\\services\\Gql::executeQuery(instance of craft\\models\\GqlSchema, 'query nodeChanges($since: String!, $site: [String]) {\n                nodesUpdatedSince (since: $since site: $site) { nodeId nodeType siteId}\n                nodesDeletedSince (since: $since) { nodeId nodeType siteId}\n            }', array(2), 'nodeChanges', true)"
        },
        {
          "call": "craft\\controllers\\GraphqlController::actionApi()"
        },
        {
          "file": "/var/www/html/vendor/yiisoft/yii2/base/InlineAction.php",
          "line": 57,
          "function": "call_user_func_array(array(2), array(0))"
        },
        {
          "file": "/var/www/html/vendor/yiisoft/yii2/base/Controller.php",
          "line": 178,
          "call": "yii\\base\\InlineAction::runWithParams(array(1))"
        },
        {
          "file": "/var/www/html/vendor/yiisoft/yii2/base/Module.php",
          "line": 552,
          "call": "yii\\base\\Controller::runAction('api', array(1))"
        },
        {
          "file": "/var/www/html/vendor/craftcms/cms/src/web/Application.php",
          "line": 301,
          "call": "yii\\base\\Module::runAction('graphql/api', array(1))"
        },
        {
          "file": "/var/www/html/vendor/craftcms/cms/src/web/Application.php",
          "line": 625,
          "call": "craft\\web\\Application::runAction('graphql/api', array(1))"
        },
        {
          "file": "/var/www/html/vendor/craftcms/cms/src/web/Application.php",
          "line": 280,
          "call": "craft\\web\\Application::_processActionRequest(instance of craft\\web\\Request)"
        },
        {
          "file": "/var/www/html/vendor/yiisoft/yii2/base/Application.php",
          "line": 384,
          "call": "craft\\web\\Application::handleRequest(instance of craft\\web\\Request)"
        },
        {
          "file": "/var/www/html/web/index.php",
          "line": 12,
          "call": "yii\\base\\Application::run()"
        }
      ]
    }
  ],
  "data": {
    "nodesUpdatedSince": null,
    "nodesDeletedSince": []
  }
}

Here is the error logged in Craft:

2022-09-26 14:56:40 [web.ERROR] [PDOException] PDOException: SQLSTATE[22P02]: Invalid text representation: 7 ERROR:  invalid input syntax for type integer: ""
CONTEXT:  unnamed portal parameter $4 = '' in /var/www/html/vendor/yiisoft/yii2/db/Command.php:1302
Stack trace:
#0 /var/www/html/vendor/yiisoft/yii2/db/Command.php(1302): PDOStatement->execute()
#1 /var/www/html/vendor/yiisoft/yii2/db/Command.php(1168): yii\db\Command->internalExecute('SELECT "e"."id"...')
#2 /var/www/html/vendor/yiisoft/yii2/db/Command.php(410): yii\db\Command->queryInternal('fetchAll', NULL)
#3 /var/www/html/vendor/yiisoft/yii2/db/Query.php(249): yii\db\Command->queryAll()
#4 /var/www/html/vendor/craftcms/cms/src/db/Query.php(247): yii\db\Query->all(NULL)
#5 /var/www/html/vendor/craftcms/gatsby-helper/src/services/Deltas.php(119): craft\db\Query->all()
#6 /var/www/html/vendor/craftcms/gatsby-helper/src/gql/resolvers/UpdatedNode.php(41): craft\gatsbyhelper\services\Deltas->getUpdatedNodesSinceTimeStamp('2022-09-25 18:5...', Array)
#7 /var/www/html/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(623): craft\gatsbyhelper\gql\resolvers\UpdatedNode::resolve(NULL, Array, Array, Object(GraphQL\Type\Definition\ResolveInfo))
#8 /var/www/html/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(550): GraphQL\Executor\ReferenceExecutor->resolveFieldValueOrError(Object(GraphQL\Type\Definition\FieldDefinition), Object(GraphQL\Language\AST\FieldNode), 'craft\\gatsbyhel...', NULL, Object(GraphQL\Type\Definition\ResolveInfo))
#9 /var/www/html/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(1195): GraphQL\Executor\ReferenceExecutor->resolveField(Object(GraphQL\Type\Definition\ObjectType), NULL, Object(ArrayObject), Array)
#10 /var/www/html/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(264): GraphQL\Executor\ReferenceExecutor->executeFields(Object(GraphQL\Type\Definition\ObjectType), NULL, Array, Object(ArrayObject))
#11 /var/www/html/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(215): GraphQL\Executor\ReferenceExecutor->executeOperation(Object(GraphQL\Language\AST\OperationDefinitionNode), NULL)
#12 /var/www/html/vendor/webonyx/graphql-php/src/Executor/Executor.php(156): GraphQL\Executor\ReferenceExecutor->doExecute()
#13 /var/www/html/vendor/webonyx/graphql-php/src/GraphQL.php(162): GraphQL\Executor\Executor::promiseToExecute(Object(GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter), Object(GraphQL\Type\Schema), Object(GraphQL\Language\AST\DocumentNode), NULL, Array, Array, 'nodeChanges', NULL)
#14 /var/www/html/vendor/webonyx/graphql-php/src/GraphQL.php(94): GraphQL\GraphQL::promiseToExecute(Object(GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter), Object(GraphQL\Type\Schema), 'query nodeChang...', NULL, Array, Array, 'nodeChanges', NULL, Array)
#15 /var/www/html/vendor/craftcms/cms/src/services/Gql.php(513): GraphQL\GraphQL::executeQuery(Object(GraphQL\Type\Schema), 'query nodeChang...', NULL, Array, Array, 'nodeChanges', NULL, Array)
#16 /var/www/html/vendor/craftcms/cms/src/controllers/GraphqlController.php(177): craft\services\Gql->executeQuery(Object(craft\models\GqlSchema), 'query nodeChang...', Array, 'nodeChanges', true)
#17 [internal function]: craft\controllers\GraphqlController->actionApi()
#18 /var/www/html/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#19 /var/www/html/vendor/yiisoft/yii2/base/Controller.php(178): yii\base\InlineAction->runWithParams(Array)
#20 /var/www/html/vendor/yiisoft/yii2/base/Module.php(552): yii\base\Controller->runAction('api', Array)
#21 /var/www/html/vendor/craftcms/cms/src/web/Application.php(301): yii\base\Module->runAction('graphql/api', Array)
#22 /var/www/html/vendor/craftcms/cms/src/web/Application.php(625): craft\web\Application->runAction('graphql/api', Array)
#23 /var/www/html/vendor/craftcms/cms/src/web/Application.php(280): craft\web\Application->_processActionRequest(Object(craft\web\Request))
#24 /var/www/html/vendor/yiisoft/yii2/base/Application.php(384): craft\web\Application->handleRequest(Object(craft\web\Request))
#25 /var/www/html/web/index.php(12): yii\base\Application->run()
#26 {main} {"memory":13091912,"exception":"[object] (PDOException(code: 22P02): SQLSTATE[22P02]: Invalid text representation: 7 ERROR:  invalid input syntax for type integer: \"\"
CONTEXT:  unnamed portal parameter $4 = '' at /var/www/html/vendor/yiisoft/yii2/db/Command.php:1302)"} 

And here's the error logged by the database (much easier to read):

2022-09-26 15:05:56.672 UTC [20127] ERROR:  invalid input syntax for type integer: ""
2022-09-26 15:05:56.672 UTC [20127] CONTEXT:  unnamed portal parameter $4 = ''
2022-09-26 15:05:56.672 UTC [20127] STATEMENT:  SELECT "e"."id", "e"."type", "es"."siteId"
    FROM "elements" "e"
    INNER JOIN "elements_sites" "es" ON ("e"."id" = "es"."elementId") AND ("es"."siteId"=$1)
    WHERE ("e"."dateDeleted" IS NULL) AND ("e"."type"<>$2) AND (("e"."dateUpdated" > $3) OR ("e"."id" IN ($4, $5))) AND ("e"."revisionId" IS NULL) AND ("e"."draftId" IS NULL)

Problem is in the OR ("e"."id" IN ($4, $5))) bit at the end there, which I tracked down to \craft\gatsbyhelper\services\Deltas::getUpdatedNodesSinceTimeStamp, specifically this bit vendor/craftcms/gatsby-helper/src/services/Deltas.php:98:

        $structureUpdates = (new Query())
            ->select(['elementId', 'structureId'])
            ->from([CraftTable::STRUCTUREELEMENTS])
            ->andWhere(['>', 'dateUpdated', Db::prepareDateForDb($timestamp)])
            ->pairs();

I checked my database and my structureelements table has a row with a NULL elementId, hence the SQL error. I don't really know anything about this table but it looks like it's a tree and that NULL element appears to be a sibling to another Navigation Node and appears to be a child of what I'm pretty sure is the backing structure to my main navigation. Ah, I did just match them by looking at the created date… I don't see this element's ID in the structureelements table. I also have 5 other NULL elementId rows here, don't know if that's relevant.

Steps to reproduce

  1. Make a new Craft site with Gatsby plugin & Navigation plugin, Gatsby front end with gatsby-source-craft.
  2. Create a navigation through the plugin.
  3. Source the navigation in Gatsby.
  4. Update the navigation.
  5. Either run a new build or be running gatsby develop and trigger a data refresh.

Note: during development, this is a non-totally-breaking issue, in that it won't cause the build to abort, but it does require me to delete my caches before I can get new data. During production builds this will cause the build to abort.

Craft CMS version

4.2.5.1

Plugin version

2.0.6

Multi-site?

No

Additional context

"gatsby-source-craft": "^3.0.0"

This is a new site, started on Craft 4. It's only existed for a few weeks so hasn't seen any major updates. I did update Navgation from 2.0.5 -> 2.0.6.

engram-design commented 2 years ago

Thanks for the info! I'm unsure if this is a Craft or Navigation (or Gatsby Source) issue.

This also might be related to another bug, which is fixed for the next release. To get the fix early, change your verbb/navigation requirement in composer.json to:

"require": {
  "verbb/navigation": "dev-craft-4 as 2.0.6",
  "...": "..."
}

Then run composer update.

zjr commented 2 years ago

I can't be quite sure if that fixed it or not. I updated the requirement and still had the problem, but then manually corrected the elementId's in my structureelements table, and, since then, I haven't had the problem recur. So, seems good?

engram-design commented 2 years ago

Hmm, I'll close for now, but will keep an eye on it.