From f2711247a820020b71b7726aaa85ab4e82e9b092 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Fri, 10 Sep 2021 14:34:13 -0700 Subject: [PATCH 1/2] fix(gatsby-source-drupal): handle edge case with deleting nodes In this case, when trying to deleting a node's references nodes, we were crashing if the referenced node had already been deleted. --- .../src/__tests__/fixtures/1593545806.json | 10 ++++++ .../src/__tests__/fixtures/article.json | 32 +++++++++++++++++++ packages/gatsby-source-drupal/src/utils.js | 20 +++++++----- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/packages/gatsby-source-drupal/src/__tests__/fixtures/1593545806.json b/packages/gatsby-source-drupal/src/__tests__/fixtures/1593545806.json index 42db4acbd30a7..b72c91cc26e0e 100644 --- a/packages/gatsby-source-drupal/src/__tests__/fixtures/1593545806.json +++ b/packages/gatsby-source-drupal/src/__tests__/fixtures/1593545806.json @@ -1,11 +1,21 @@ { "timestamp": 1593545807, "entities": [ + { + "action": "delete", + "id": "article-71", + "type": "node--article" + }, { "action": "delete", "id": "file-4", "type": "file--file" }, + { + "action": "delete", + "id": "does-not-exist", + "type": "file--file" + }, { "jsonapi": { "version": "1.0", diff --git a/packages/gatsby-source-drupal/src/__tests__/fixtures/article.json b/packages/gatsby-source-drupal/src/__tests__/fixtures/article.json index bf77e25dc4d9f..e047e719fef3b 100644 --- a/packages/gatsby-source-drupal/src/__tests__/fixtures/article.json +++ b/packages/gatsby-source-drupal/src/__tests__/fixtures/article.json @@ -73,6 +73,38 @@ "data": null } } + }, + { + "type": "node--article", + "id": "article-71", + "attributes": { + "id": 223, + "uuid": "article-71", + "title": "Article #71", + "body": "Proin pulvinar hendrerit magna nec maximus. Donec rhoncus libero ac nisi porttitor pulvinar. Quisque semper ultricies nulla sit amet vestibulum. Ut vel libero erat. Ut ultrices eleifend scelerisque. Nam non massa sit amet magna molestie tempus vel non neque. Praesent ac est congue, euismod mi ut, tristique mi. Etiam dapibus feugiat lectus, vel condimentum nisl maximus et. Praesent et placerat magna. Sed nec risus non ipsum venenatis placerat. Vestibulum vitae felis eget nunc mattis congue. Morbi volutpat odio purus. Donec placerat massa sed neque molestie, sed finibus nibh scelerisque. In faucibus ante tortor, in efficitur lectus feugiat vitae. Aliquam sodales mollis consectetur." + }, + "relationships": { + "field_secondary_image": { + "data": [ + { + "type": "file--file", + "id": "file-4" + } + ] + }, + "field_secondary_multiple_image": { + "data": [ + { + "type": "file--file", + "id": "file-3" + }, + { + "type": "file--file", + "id": "file-4" + } + ] + } + } } ], "links": { diff --git a/packages/gatsby-source-drupal/src/utils.js b/packages/gatsby-source-drupal/src/utils.js index bd7b6cc3538f5..cdf7afdecc0ed 100644 --- a/packages/gatsby-source-drupal/src/utils.js +++ b/packages/gatsby-source-drupal/src/utils.js @@ -171,15 +171,19 @@ const handleDeletedNode = async ({ referencedNodes = referencedNodes.filter(nId => nId !== deletedNode.id) referencedNodesLookup.set(node, referencedNodes) } - // Recreate the referenced node with its now cleaned-up relationships. - if (node.internal.owner) { - delete node.internal.owner - } - if (node.fields) { - delete node.fields + + // The referenced node might have already been deleted. + if (node) { + // Recreate the referenced node with its now cleaned-up relationships. + if (node.internal.owner) { + delete node.internal.owner + } + if (node.fields) { + delete node.fields + } + node.internal.contentDigest = createContentDigest(node) + actions.createNode(node) } - node.internal.contentDigest = createContentDigest(node) - actions.createNode(node) }) }) From 210fb541dbe6b919163555f65394a18588804ccf Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Fri, 10 Sep 2021 14:36:29 -0700 Subject: [PATCH 2/2] also cleanup referencedNodesLookup --- packages/gatsby-source-drupal/src/utils.js | 56 ++++++++++++---------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/packages/gatsby-source-drupal/src/utils.js b/packages/gatsby-source-drupal/src/utils.js index cdf7afdecc0ed..ed19cbca059b1 100644 --- a/packages/gatsby-source-drupal/src/utils.js +++ b/packages/gatsby-source-drupal/src/utils.js @@ -136,8 +136,9 @@ const handleDeletedNode = async ({ return deletedNode } - // Remove the deleted node from backRefsNamesLookup + // Remove the deleted node from backRefsNamesLookup and referencedNodesLookup backRefsNamesLookup.delete(deletedNode) + referencedNodesLookup.delete(deletedNode) // Remove relationships from other nodes and re-create them. Object.keys(deletedNode.relationships).forEach(key => { @@ -145,35 +146,38 @@ const handleDeletedNode = async ({ ids = [].concat(ids) ids.forEach(id => { const node = getNode(id) - let referencedNodes = referencedNodesLookup.get(node) - if (referencedNodes?.includes(deletedNode.id)) { - // Loop over relationships and cleanup references. - Object.entries(node.relationships).forEach(([key, value]) => { - // If a string ref matches, delete it. - if (_.isString(value) && value === deletedNode.id) { - delete node.relationships[key] - } - - // If it's an array, filter, then check if the array is empty and then delete - // if so - if (_.isArray(value)) { - value = value.filter(v => v !== deletedNode.id) - - if (value.length === 0) { + + // The referenced node might have already been deleted. + if (node) { + let referencedNodes = referencedNodesLookup.get(node) + if (referencedNodes?.includes(deletedNode.id)) { + // Loop over relationships and cleanup references. + Object.entries(node.relationships).forEach(([key, value]) => { + // If a string ref matches, delete it. + if (_.isString(value) && value === deletedNode.id) { delete node.relationships[key] - } else { - node.relationships[key] = value } - } - }) - // Remove deleted node from array of referencedNodes - referencedNodes = referencedNodes.filter(nId => nId !== deletedNode.id) - referencedNodesLookup.set(node, referencedNodes) - } + // If it's an array, filter, then check if the array is empty and then delete + // if so + if (_.isArray(value)) { + value = value.filter(v => v !== deletedNode.id) + + if (value.length === 0) { + delete node.relationships[key] + } else { + node.relationships[key] = value + } + } + }) + + // Remove deleted node from array of referencedNodes + referencedNodes = referencedNodes.filter( + nId => nId !== deletedNode.id + ) + referencedNodesLookup.set(node, referencedNodes) + } - // The referenced node might have already been deleted. - if (node) { // Recreate the referenced node with its now cleaned-up relationships. if (node.internal.owner) { delete node.internal.owner