Problem/Motivation

If a request hits on a stale hook registry (during a deploy) i.e. the code on disk no longer provides an implementation the registry lists, CallableResolver throws. ModuleHandler::alter() reaches this code for every alter hook, so the whole site fatals. Similar situation arises in ThemeManager::alterForTheme().

ModuleHandler::getHookImplementationList() resolves every identifier in it with no guard:

// core/lib/Drupal/Core/Extension/ModuleHandler.php
foreach ($hook_list as $identifier => $module) {
  if (isset($this->moduleList[$module]) || $module === 'core') {
    $listeners[] = $this->callableResolver->getCallableFromDefinition($identifier);
    $modules[] = $module;
  }
}

Again. similar in: ThemeManager::getImplementationsForTheme().

Drupal 10 tolerated this: ModuleHandler::verifyImplementations() dropped implementations whose function had gone and carried on.

Three ways it goes stale

1. a procedural implementation is deleted
2. a hook class is removed
3. a hook method is renamed

Steps to reproduce

1. add a hook_page_attachments_alter to any module
2. Rebuild, so the registry records it: drush cr
3. delete the hook (don't rebuild registry)
4. request any page
5. observe:

THROWN: InvalidArgumentException: Class "XXX_page_attachments_alter" does not exist.
  at /var/www/html/docroot/core/lib/Drupal/Core/DependencyInjection/ClassResolver.php:32

Proposed resolution

Catch the resolver's InvalidArgumentException, skip that implementation and warn.

Remaining risk

If the missing implementation is a hook_query_alter() that adds an access restriction, the site stays up but serves data it should not.

Issue fork drupal-3622228

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

paranojik created an issue. See original summary.

nicxvan’s picture

Version: 11.4.x-dev » main
Status: Active » Postponed (maintainer needs more info)

Hi, thanks for the report.

Issues for Drupal core should be targeted to the 'main' branch, our primary development branch. Changes are made on the main branch first, and are then back ported as needed according to the Core change policies. The version the problem was discovered on should be stated in the issue summary Problem/Motivation section. Thanks.

Also, the title should be a description of what is being fixed or improved. The title is used as the git commit message so it should be meaningful and concise. See List of issue fields.

Finally, the issue summary could use some formatting so it is easier for reviewers to read. It looks like it is Markdown but should be HTML and is rather verbose. In fact, this reads like prose from an AI. If so, in Drupal core, we would like concise summaries that are in the reporter's own words. Of course, giving allowance for anyone who is not a native English speaker. See the orange warning box in the policy on the use of AI when contributing to Drupal.

Don't just copy and paste the output verbatim.

Use your own words, and be concise.

Also i haven't read through the full issue summary, but search for duplicates as well please.

paranojik’s picture

Title: A stale hook registry entry fatals every request instead of being skipped » Skip stale hook registry entries to prevent WSOD
Issue summary: View changes
paranojik’s picture

Issue summary: View changes
nicxvan’s picture

Status: Postponed (maintainer needs more info) » Active

Thank you for the cleanup!

paranojik’s picture

Status: Active » Needs review
oily’s picture

Have reviewed the code, IS and comments. Added comments to the MR. MR is breaking due to cspell. Need to get pipeline green then can run the test-only test to check the test coverage.

oily’s picture

Status: Needs review » Needs work
oily’s picture

paranojik please declare it if you are using AI. It is a requirement.

oily’s picture

Pipeline is now green. Here is the test-only https://git.drupalcode.org/issue/drupal-3622228/-/jobs/12136101. There are 14 test failures. I think that is what should be output by that test. It is a bit confusing because there are errors about the new definitionExists() method not being found (because it is in the fix code that test-only excludes).

oily’s picture

Code comment resolved. RTBTC.

oily’s picture

Status: Needs work » Reviewed & tested by the community
nicxvan’s picture

Assigned: Unassigned » nicxvan
Status: Reviewed & tested by the community » Postponed (maintainer needs more info)

Thank you guys, I'm going to put this in pmni because I'd like to take a careful review, there are a few related issues, but I can't look until early next week.

I'm going to assign it to myself too.

nicxvan’s picture

Status: Postponed (maintainer needs more info) » Needs review
Issue tags: +Needs subsystem maintainer review

This might be a better status with the issue tag, I'll keep this assigned to myself.

nicxvan’s picture

This is a duplicate of #3495051: ModuleHandler::invokeAllWith() does not check listener is actually callable at the moment

Usually we close the newer issue, but this has an actual MR.

I took a quick look, I'm not sure a trait is the way to go? Why was that chosen over just a try catch?

oily’s picture

The steps to reproduce:

1. add a hook_module_implements_alter to any module

But drupal docs state that that hook is removed in 12.0.

paranojik’s picture

Issue summary: View changes
paranojik’s picture

@oily, thanks for the remark. I started with a 11.x patch and failed to check after re-rolling on main. Fixed the description.

@nicxvan:

I took a quick look, I'm not sure a trait is the way to go? Why was that chosen over just a try catch?

A similar situation arises in ThemeManager. I updated the ticket description.