wpengine / wp-graphql-content-blocks

Plugin that extends WPGraphQL to support querying (Gutenberg) Blocks as data

Home Page:https://faustjs.org/docs/gutenberg/wp-graphql-content-blocks

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ApolloError: Internal server error when querying "dropCap" attribute on core/paragraph block

jan-clockworkwp opened this issue · comments

When I query core/paragraph block with full list of attributes, I am getting the following FE error:

error - GraphQL errors: [
  {
    debugMessage: 'Undefined array key "dropCap"',
    message: 'Internal server error',
    extensions: { category: 'internal' },
    locations: [ [Object] ],
    path: [ 'page', 'editorBlocks', 0, 'attributes', 'dropCap' ]
  }
]

and GraphQL error:

"errors": [
  {
    "debugMessage": "Undefined array key \"dropCap\"",
    "message": "Internal server error",
    "extensions": {
      "category": "internal"
    },
    "locations": [
      {
        "line": 20,
        "column": 7
      }
    ],
    "path": [
      "page",
      "editorBlocks",
      0,
      "attributes",
      "dropCap"
    ]
  }
]

In the Wp Admin GraphQL IDE, dropCaps attributed is in the list of available attributes.

Seems like the issue is only with the attribute dropCap. When it is not in the query, all works as expected. This behaviour is on:

  • WordPress 6.5.2
  • WPGraphQL Content Blocks 4.0.0

Additional relevant plugins and packages used on FE:

"@apollo/client": "^3.9.11",
"@faustwp/blocks": "^4.0.0",
"@faustwp/cli": "^3.0.1",
"@faustwp/core": "^3.0.1", 
"@wordpress/base-styles": "^4.47.0",
"@wordpress/block-library": "^8.33.0",
"@wordpress/style-engine": "^1.39.0",
"@wordpress/scripts": "^27.7.0",
"@faustwp/block-editor-utils": "^0.2.0",

Additional relevant plugins and packages used on BE:

"wpackagist-plugin/faustwp":"1.2.3",
"wpackagist-plugin/wp-graphql":"1.23.0",
"wpackagist-plugin/wpgraphql-acf":"2.2.0",
"wpackagist-plugin/wpgraphql-smart-cache":"1.3.1",
"wpengine/advanced-custom-fields-pro": "^6.2.9",
"wpengine/wp-graphql-content-blocks": "^4.0.0",

Any idea what is going on? Could #182 be relevant to this issue?

Hey @jan-clockworkwp thank you for the report. Could you provide me with the saved database post content so I could try to reproduce as well?
I wasn't able to reproduce with a sample paragraph example:

<!-- wp:paragraph {"dropCap":true} -->
<p class="has-drop-cap">asdasdasasdasda sdasdasdasd</p>
<!-- /wp:paragraph -->

Hi @theodesp, sure! Here is the post content from the database:

<!-- wp:paragraph -->
<p>Actually hell of vape poke synth celiac bitters wolf austin lo-fi edison bulb knausgaard. Stumptown hashtag grailed af. Subway tile man bun grailed biodiesel wayfarers cold-pressed. Prism taiyaki thundercats fanny pack tacos cred neutra cardigan church-key copper mug, tofu trust fund austin.</p>
<!-- /wp:paragraph -->

To give you a bit more background on why I am facing this issue, well, I am working on Faustjs with TypeScript. Because graphql-codegen does not parse fragments from the node modules, or at least I was not able to make it parse them, I am generating a file with all block fragments using a script similar to this https://gist.github.com/mrclay/f1a949d1be18a44281a1556fe2765971
that basically just takes all core blocks from the @faustwp/blocks package and generates a file with all fragments and attributes to ensure that all fragments are typed properly. Then, I can use it in all templates as one fragment and also have all custom blocks' fragments included. This is the reason why all attributes for all blocks are present in my queries. Therefore, I could spot the issue on any paragraph block that does not have the dropCap attribute set (as by default, a paragraph block does not have it set).
Should a query with an extra attribute that is not present or set on the block gracefully fallback to something else instead of throwing a server error in Apollo Client? Perhaps I am doing something incorrectly and would greatly appreciate guidance on how to properly address this issue. As a temporary solution, I am removing the dropCap attribute from the query.
Thank you for looking into this!

@theodesp I'm not by my computer to confirm, but sounds like the error is coming from here, since most those variable key lookups aren't checking if the key exists on the array first.

Hey @jan-clockworkwp. That is strange. I still can't reproduce with a plain paragraph. I can resolve the dropCap fields fine in WordPress 6.5.

I see that the "dropCap" attribute for the CoreParagraph has a default value so this should not fail:

https://github.com/WordPress/gutenberg/blob/trunk/packages/block-library/src/paragraph/block.json#L21-L23

"dropCap": {
    "type": "boolean",
    "default": false
  },

Hey @theodesp, thanks for getting back to me. Hmm, pretty strange. From what I can see in the schema, dropCap: Boolean! is essentially the only required attribute. Could that be causing an issue in the code here ?

Additionally, I have looked into whether an attribute marked as required in the schema could be causing a problem. I was able to replicate the issue with the PostAuthorName core block and any attribute that is marked in the schema as required, such as the isLink attribute. Here are the errors for both Paragraph and PostAuthorName plain blocks with not additional options set:

"errors": [
    {
      "debugMessage": "Undefined array key \"dropCap\"",
      "message": "Internal server error",
      "extensions": {
        "category": "internal"
      },
      "locations": [
        {
          "line": 20,
          "column": 7
        }
      ],
      "path": [
        "page",
        "editorBlocks",
        0,
        "attributes",
        "dropCap"
      ]
    },
    {
      "debugMessage": "Undefined array key \"isLink\"",
      "message": "Internal server error",
      "extensions": {
        "category": "internal"
      },
      "locations": [
        {
          "line": 29,
          "column": 7
        }
      ],
      "path": [
        "page",
        "editorBlocks",
        2,
        "attributes",
        "isLink"
      ]
    }
  ],

Yes, if the field has a default value, then we register it as required since it needs to have a value:

The code that deals with this logic is here:

if ( null !== $type ) {
$default_value = $attribute['default'] ?? null;
if ( isset( $default_value ) ) {
$type = [ 'non_null' => $type ];
}
}

However when the resolved field is not present, it should fall back to its default value which is taken from their field config:

if ( empty( $result[ $key ] ) ) {
$result[ $key ] = $attributes[ $key ] ?? $default;
}

So Im not sure where the logic fails in that case

So Im not sure where the logic fails in that case

As mentioned above, collectively that method needs to be using isset() or array_key_exists(), on both the $result and $attributes arrays (in that second snippet you only check the result, but iirc I get PHP warnings also before the switch(). If you bump up the strictness on either PHPCS or PHPStan it should catch them)

Hey @theodesp is this something we can hope of being considered in the next release of the plugin? Many thanks.

Confirming that the #245 solves the issue with native WP blocks attributes like, for example, dropCap on core/paragraph block and isStackedOnMobile on CoreColumns block. Thank you for solving this @justlevine @theodesp.