Problem/Motivation

It is not possible to index content after disabling the forum module. The comment module is trying to load a field when indexing and this field does not exist. This is the line:

  $comment_statistics = $entities[$record->entity_id]->get($field_name);

To reproduce it you also need at least active comment field on the given entity type - eg
Forum comments + article comments -> disable forum -> forum comment field is removed -> view a node with a comment from the forum comment field (since removed).
To reproduce this behavior you need to:

  1. install Forum module
  2. add forum comment field to an article node type
  3. uninstall Forum module
  4. view a node with a comment from the forum comment field

Proposed resolution

Skip fields that entity does not have.

Remaining tasks

None.

User interface changes

None.

API changes

None.


Original report by @codeyourdream

Original issue title: After uninstalling a node type module, nodes are not loadable, breaking search indexing and admin/content/node

Problem/Motivation

[Drupal 7] If by some reason node can't be loaded (for example, node's module disabled, but the row in {node} table still exists), then site indexing process interrupts on this node.

function _node_index_node($node) {
  $node = node_load($node->nid);

  // Save the changed time of the most recent indexed node, for the search
  // results half-life calculation.
  variable_set('node_cron_last', $node->changed);

  // Render the node.
  $build = node_view($node, 'search_index');
  ......

If node_load() returns FALSE, then this value (FALSE) will be transferred to node_view() and will result in an error "EntityMalformedException: Missing bundle property on entity of type node. in entity_extract_ids() (line 7633 of /var/www/creativepro/includes/common.inc)" and interrupting site indexing.

Proposed resolution

We need to add check for successful node_load() to _node_index_node() function:

function _node_index_node($node) {
  $nid = $node->nid;
  if(!($node = node_load($nid))) {
    watchdog('node', t('Can\'t load node @nid during site indexing.'), array('@nid' => $nid), WATCHDOG_WARNING);
    return;
  }

  // Save the changed time of the most recent indexed node, for the search
  // results half-life calculation.
  variable_set('node_cron_last', $node->changed);

  // Render the node.
  $build = node_view($node, 'search_index');
....

Comments

codeyourdream’s picture

Status: Active » Needs review
StatusFileSize
new1005 bytes

Patch.

TonyK’s picture

Title: Not-loadable nodes breaks site indexing » Not loadable nodes break site indexing
Component: node system » search.module
Priority: Normal » Major

This issue relates only to search module and I think it should have major priority because it makes a part of nodes not indexable.

TonyK’s picture

To reproduce disable Forum module (provided the site has nodes of type forum) and try to re-index nodes.

catch’s picture

Version: 7.22 » 8.x-dev
Priority: Major » Normal
Issue tags: +Needs backport to D7

There's already a critical issue to address behaviour like this: #1199946: Disabled modules are broken beyond repair so the "disable" functionality needs to be removed.

Downgrading to normal - if you disable forum module while having forum nodes still on your site many more things can break than this, which is what the above issue is for.

Also needs fixing in 8.x first then backporting.

TonyK’s picture

@catch
#1199946: Disabled modules are broken beyond repair so the "disable" functionality needs to be removed seem to be a big problem with Drupal architecture. Fixing it (whenever it happens) will likely introduce non-backward compatible changes to Drupal core. Are there really any chances that it will ever get to D7?

jhodgdon’s picture

Issue summary: View changes
Status: Needs review » Needs work

The code is quite different in Drupal 8 now.

For one thing, it's NodeSearch::updateIndex(), and it is doing basically a query to get the node IDs from the node table, and then calling

   $node_storage = $this->entityManager->getStorageController('node');
    foreach ($node_storage->loadMultiple($nids) as $node) {

I have no idea what will happen if loadMultiple() is unable to load the node for whatever reason... probably an exception? Is it even possible to get into that situation in Drupal 8? Can we make a test that reproduces this behavior?

Regarding disabling/uninstalling modules... If you uninstall the Forum module, I just looked at the code and it does *not* remove any nodes when you uninstall the module -- it removes some taxonomy vocabs and some fields related to forums, but it will leave the nodes there.

So we can probably make a test out of this: install/enable Forum and Search, make a forum term and a couple of forum nodes, plus then a couple of other nodes, uninstall forum, and then run cron to index the site and see what happens (which nodes, if any, are indexed, and does cron finish, and is there an error message?).

You could try this manually and if it makes errors, then write a SimpleTest for it. Then we could either try to fix the actual bug (make it so that loadMultiple does not die when a node-defining module is removed), or we could try to work around it in search (do a try/catch on the loadMultiple), or who knows.

What happens now if you add Forum nodes, uninstall Forum, and then go to a node/### page for one of those forum nodes? What should happen?

berdir’s picture

loadMultiple() should simply return an empty array and make this a no-op and just skip the foreach. Assuming that doesn't break anything later on, we should be fine.

jhodgdon’s picture

OK then. I think we should make a test for D8 as outlined in comment #6. Assuming it passes without any code change (as #7 suggests it will), we can then commit the test and move on to Drupal 7. Any takers?

marthinal’s picture

Status: Needs work » Needs review
StatusFileSize
new1.49 KB

I was reproducing the bug creating forum content and others(page,article...). Then disabling Forum module.

If you try to index the content, it will be not possible. The problem seems to be at this line (comment module):

$comment_statistics = $entities[$record->entity_id]->get($field_name);

This is because $field_name == comment_forum.

I have fixed the problem with this patch. Now I can reindex the content and everything seems ok.

Let's take a look at the test result.

I don't know if we can fix this problem from other place. But this get() method break the index process.

berdir’s picture

Status: Needs review » Needs work

Use $entities[$record->entity_id]->hasField($field_name). getField() isn't bundle specific, so that doesn't work like that. If anything, you'd have to use getInstance().

marthinal’s picture

Status: Needs work » Needs review
StatusFileSize
new1.58 KB

Using hasField() there were problems so I decided to use getInstance as you proposed.

berdir’s picture

What kind of problems? The function was added for exactly this use case, if there's a problem, we should fix it.

marthinal’s picture

StatusFileSize
new1.53 KB

@Berdir upppss Probably I made something wrong using hasField. I'm sorry. Attached again using hasField.

Status: Needs review » Needs work

The last submitted patch, 11: search_index-1966448-11.patch, failed testing.

jhodgdon’s picture

Status: Needs work » Needs review

The last patch doesn't look like it got tested, so resetting status... Actually I'm not seeing that last file in Recent Files? Um... maybe upload it again?

marthinal’s picture

StatusFileSize
new743 bytes
new1.62 KB

let's try again, sure.

berdir’s picture

This isn't really search specific problem, it's the generic comment entity load hook. So anything that would attempt to load those entities would then fail.

Not 100% sure what exactly is going on, but it seems that the data there shouldn't exist anymore if the field doesn't, so it would never have to attempt to set it.

Maybe @larowlan can comment on this.

larowlan’s picture

Berdir pointed me at this issue, and yeah not sure why there would be data for a field_id if that field no longer existed. Can you update the issue summary with the field_id you're seeing and the entity type?
Thanks

marthinal’s picture

Issue summary: View changes
marthinal’s picture

StatusFileSize
new166.81 KB

Screenshot attached.

jhodgdon’s picture

Title: Not loadable nodes break site indexing » After uninstalling a node type module, nodes are not loadable, breaking search indexing and admin/content/node
Component: search.module » field system
Issue summary: View changes
Status: Needs review » Needs work
Issue tags: +Needs tests

OK, let's step back here.

I just went to simplytest.me, and spun up a Drupal 8 alpha 4 site, which isn't -dev but has the advantage of being quick to set up. Did the following:
- Installed using standard install profile in English.
- Enabled Forum (Search/Comment were enabled)
- Added a Forum node. Added a comment to it.
- Went back to the modules uninstall page and uninstalled forum. Verified it is not enabled on the Extend page.
- Clicked on "Content" (admin/content/node). Instead of the Content page, I got this error:

InvalidArgumentException: Field comment_forum is unknown. in Drupal\Core\Entity\ContentEntityBase->getTranslatedField() (line 398 of /home/s98ab04be11a0bfa/www/core/lib/Drupal/Core/Entity/ContentEntityBase.php).

So this is definitely a problem in Drupal Core, independent of search.module, at least as of alpha8. I didn't get as far as trying to index the site, but if you can't even get to the admin/content/node page, there isn't much point in trying to index your site for search.

I think it would be easy to make a test that reproduced these steps, and then we could verify that the patch would fix the behavior.

At this point, I'm thinking that for 8.x it is not a search module problem. Seems like field.system?

berdir’s picture

Component: field system » comment.module

It's the field system that causes the error, but comment.module is the actual cause here, which does not use it correctly.

larowlan’s picture

Assigned: Unassigned » larowlan

working on tests

marthinal’s picture

StatusFileSize
new3.72 KB

@larowlan I was working on this test last weekend and today a little bit because I had some problems to reproduce using a minimal installation. This test reproduce the error and #16 fix it. The only problem, other tests fail because there's a conflict enabling and disabling modules. So I know you are working on it and maybe this test is useful to finish your test or... I don't know at what point you are.

larowlan’s picture

Assigned: larowlan » Unassigned
Status: Needs work » Needs review
StatusFileSize
new2.13 KB
new2.13 KB
new2.86 KB

thanks @marthinal
I added this to ForumUninstall test, it is already concerned with field behaviour when disabling forum module.
To reproduce it you also need at least active comment field on the given entity type - eg
Forum comments + article comments -> disable forum -> forum comment field is removed -> view a node with a comment from the forum comment field (since removed).

larowlan’s picture

Issue tags: -Needs backport to D7

No such thing as comment-field in D7

jhodgdon’s picture

If we're not marking this as 'needs backport', then we need to file a new issue with the original report from D7, because search indexing breaks due to this same problem in D7.

andypost’s picture

Status: Needs review » Reviewed & tested by the community

Suppose D7 case is different, patch is awesome

jhodgdon’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs backport to D7

Actually, this isn't quite right. The test-only patch did not fail the test. Therefore, it is not a valid test of this bug.

And let's go ahead and leave the backport tag. Although the patch will be different, and the underlying cause is a bit different, the bug is pretty much the same.

larowlan’s picture

The tests are still running?

jhodgdon’s picture

Status: Needs work » Needs review

Oh sorry. I saw the green and didn't look at the details. The D6 issue page display was a lot easier to scan. :(

Anyway, let's leave this at "needs review" until the tests have failed/passed appropriately.

Status: Needs review » Needs work

The last submitted patch, 25: comment-disabled-field-1966448.25.fail_.patch, failed testing.

larowlan’s picture

Fail test failed.... still waiting on pass

jhodgdon’s picture

Status: Needs work » Reviewed & tested by the community

Excellent! I am in agreement that this is RTBC assuming the other test passes, in which case the test bot will set it back to needs work.

alexpott’s picture

Title: After uninstalling a node type module, nodes are not loadable, breaking search indexing and admin/content/node » comment_entity_load breaks after disabling the fourm module
Issue summary: View changes
Issue tags: -Needs tests, -Needs backport to D7 +Needs issue summary update

So the issue title and summary are now completely out of whack as it refers to both the D8 and D7 issue. It's hard to know what to do here. But the actual issue summary and title need to relate to the rtbced patch.

Also since this this patch is not backportable removing that tag. Not sure what to do now about the D7 issue - ideally we would have created a new issue when the new d8 bug was found.

alexpott’s picture

Issue summary: View changes

Reading #25 makes me realise my issue summary is not quite correct - updated steps to reproduce.

alexpott’s picture

jhodgdon’s picture

I added a new issue for D7:
#2153999: After disabling Forum module, cannot do search indexing
It references this one as 'related'.

alexpott’s picture

Title: comment_entity_load breaks after disabling the fourm module » comment_entity_load() breaks after disabling the Forum module
Status: Reviewed & tested by the community » Fixed
Issue tags: -Needs issue summary update

Committed 4a80834 and pushed to 8.x. Thanks!

And @jhogdon thanks for opening the other issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.