Session Limit's \Drupal\session_limit\Services\SessionLimit class currently type-hints the default ModuleHandler class instead of the interface. This prevents custom overrides of ModuleHandler, for example by Hux and Hook Event Dispatcher.

Problem/Motivation

Updated Hook Event Dispatcher from 3.2.0 to 3.3.1, now getting fatal errors like this:

The website encountered an unexpected error. Please try again later.
TypeError: Drupal\session_limit\Services\SessionLimit::__construct(): Argument #6 ($moduleHandler) must be of type Drupal\Core\Extension\ModuleHandler, Drupal\hook_event_dispatcher\HookEventDispatcherModuleHandler given, called in E:\Web\Omnipedia\Web\drupal\core\lib\Drupal\Component\DependencyInjection\Container.php on line 262 in Drupal\session_limit\Services\SessionLimit->__construct() (line 119 of modules\contrib\session_limit\src\Services\SessionLimit.php).

Drupal\session_limit\Services\SessionLimit->__construct(Object, Object, Object, Object, Object, Object, Object, Object) (Line: 262)
Drupal\Component\DependencyInjection\Container->createService(Array, 'session_limit') (Line: 176)
Drupal\Component\DependencyInjection\Container->get('session_limit') (Line: 136)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.request') (Line: 134)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 80)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 50)
Drupal\ban\BanMiddleware->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 49)
Drupal\remove_http_headers\StackMiddleware\RemoveHttpHeadersMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 709)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

Steps to reproduce

Install Hook Event Dispatcher 3.3.0+ after installing any module that injects the module_handler service with the parameter being type-hinted to the core ModuleHandler class instead of ModuleHandlerInterface. This should result in a similar fatal error to the above. The module in the error is Session Limit, and the error causing parameter can be found in Services/SessionLimit::__construct()

Proposed resolution

Change type-hint from the default service implementation \Drupal\Core\Extension\ModuleHandler to the interface \Drupal\Core\Extension\ModuleHandlerInterface.

Remaining tasks

Make the changes above.

User interface changes

None.

API changes

Unsure?

Data model changes

None?

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

Ambient.Impact created an issue. See original summary.

ambient.impact’s picture

By the way, fatal error aside, the work in #3277301: Adapt to centralised hook dispatcher in Drupal 9.4 is really neat and awesome to see moving forward. I suggested decorating the module handler service a couple of years ago to @pdenooijer but implementing it at the time was more significantly more difficult due to core not being in the place it is now.

el7cosmos’s picture

Indeed, it is easier because of the changes in 9.4.

IMO this should be changed in the Session Limit itself, type hinting to an interface rather than implementation is better, also there are other projects that decorate the module handler.

benaboki’s picture

Upgrading to 3.3 from 3.2 is also giving me errors. I fixed some by patching facets (https://www.drupal.org/project/facets/issues/3308343). This replaces ModuleHandler with ModuleHandlerInterface.

The website encountered an unexpected error. Please try again later.
TypeError: Argument 2 passed to Drupal\openid_connect\OpenIDConnectClaims::__construct() must be an instance of Drupal\Core\Extension\ModuleHandler, instance of Drupal\hook_event_dispatcher\HookEventDispatcherModuleHandler given, called in /var/www/ipbes/web/core/lib/Drupal/Component/DependencyInjection/Container.php on line 262 in Drupal\openid_connect\OpenIDConnectClaims->__construct() (line 56 of modules/contrib/openid_connect/src/OpenIDConnectClaims.php).
Drupal\openid_connect\OpenIDConnectClaims->__construct(Object, Object) (Line: 262)
Drupal\Component\DependencyInjection\Container->createService(Array, 'openid_connect.claims') (Line: 176)
Drupal\Component\DependencyInjection\Container->get('openid_connect.claims') (Line: 68)
Drupal\openid_connect\Form\OpenIDConnectLoginForm::create(Object) (Line: 28)
Drupal\Core\DependencyInjection\ClassResolver->getInstanceFromDefinition('Drupal\openid_connect\Form\OpenIDConnectLoginForm') (Line: 193)
Drupal\Core\Form\FormBuilder->getFormId('Drupal\openid_connect\Form\OpenIDConnectLoginForm', Object) (Line: 227)
Drupal\Core\Form\FormBuilder->buildForm('Drupal\openid_connect\Form\OpenIDConnectLoginForm', Object) (Line: 219)
Drupal\Core\Form\FormBuilder->getForm('Drupal\openid_connect\Form\OpenIDConnectLoginForm') (Line: 185)
openid_connect_form_user_login_form_alter(Array, Object, 'user_login_form') (Line: 562)
Drupal\Core\Extension\ModuleHandler->alter('form', Array, Object, 'user_login_form') (Line: 114)
Drupal\hook_event_dispatcher\HookEventDispatcherModuleHandler->alter(Array, Array, Object, 'user_login_form') (Line: 835)
Drupal\Core\Form\FormBuilder->prepareForm('user_login_form', Array, Object) (Line: 279)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 73)
Drupal\Core\Controller\FormController->getContentResult(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 564)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 158)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 80)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 709)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
benaboki’s picture

svendecabooter’s picture

Same problem occurs in combination with the easy_breadcrumb module.
Patch to fix this in that module: https://www.drupal.org/project/easy_breadcrumb/issues/3307333

dpi’s picture

Title: Fatal error when updating to 3.3.0 due to new decorated module handler not extending core's » Session Limit should typehint modulehandler interface rather than a specific implementation
Issue summary: View changes

This is a problem with Session Limit. The project should be typehinting the interface, not the concrete implementation.

This module should extend the core class to avoid breaking such expectations.

This would defeat one of the reasons for having service interfaces. There should not be a need to extend any Core service, I recommend mentally assuming most core services are marked final in order to avoid this kind of issue.

---

Moving to the appropriate queue and reformatting IS.

dpi’s picture

Project: Hook Event Dispatcher » Session Limit
Version: 3.3.1 » 2.0.0-beta2
ambient.impact’s picture

This is a problem with Session Limit. The project should be typehinting the interface, not the concrete implementation.

You're right. I was in a bit of a rush, so didn't look too closely at Hook Event Dispatcher class, which does in fact implement \Drupal\Core\Extension\ModuleHandlerInterface as is best practice.

ambient.impact’s picture

Title: Session Limit should typehint modulehandler interface rather than a specific implementation » Services\SessionLimit should type-hint ModuleHandlerInterface rather than a specific implementation
Issue summary: View changes

Cleaned up issue summary, and rephrased to reflect the issue being moved to the Session Limit issue queue.

ambient.impact’s picture

ambient.impact’s picture

Looks like there are a bunch of dependencies in Services\SessionLimit that are type-hinted to the core classes rather than interfaces. I can change the scope of this issue to fix those too if you all are alright with it.

ambient.impact’s picture

Status: Active » Needs review

jpoesen’s picture

Confirming that the patch in #15 (MR 5) fixes the problem.

Thanks, @Ambient.Impact!

Environment:
- Drupal 9.4.5
- session_limit 2.0.0-beta2

igork96’s picture

StatusFileSize
new1.74 KB

Here is a patch for fixing the issue. Please review it.

alina.basarabeanu’s picture

Using
- hook_event_dispatcher 4.0.0-beta1
- Drupal core 9.5.9
- session_limit 2.0.0-beta3
I get the following error:
Argument #6 ($moduleHandler) must be of type Drupal\Core\Extension\ModuleHandler, Drupal\hook_event_dispatcher\HookEventDispatcherModuleHandler given, called in /var/www/html/docroot/core/lib/Drupal/Component/DependencyInjection/Container.php on line 259

I've applied the patch from #17 and the error is fixed.

fskreuz’s picture

Title: Services\SessionLimit should type-hint ModuleHandlerInterface rather than a specific implementation » Services\SessionLimit should type-hint dependencies using interfaces
Related issues: +#3011009: Use AccountProxyInterface instead of AccountProxy
StatusFileSize
new4.03 KB

Updated patch to change all the dependencies to use interfaces. Problems will occur eventually with the others, makes sense to fix them all in one go.

k3vin_nl’s picture

Confirming the latest patch #19 works for us.

nimoatwoodway’s picture

Confirming the latest patch #19 works for us.

fskreuz’s picture

Version: 2.0.0-beta2 » 2.0.x-dev
StatusFileSize
new4.23 KB

Reroll of #19

lisotton’s picture

Status: Needs review » Reviewed & tested by the community

I applied the #22 and it worked fine with Hook Event Dispatcher.
Moving it to RTBC.

vladimiraus’s picture

Status: Reviewed & tested by the community » Closed (duplicate)
Parent issue: » #3361326: Fix the issues reported by phpcs and phpstan

Looks like partial duplicate of #3361326: Fix the issues reported by phpcs and phpstan with no proper MR.

fskreuz’s picture

Status: Closed (duplicate) » Needs review
Related issues: +#3448638: Error: Call to a member function get() on null in Drupal\session_limit\Services\SessionLimit->getMasqueradeIgnore()
StatusFileSize
new6.76 KB

Re-opening with updated patch. https://www.drupal.org/project/session_limit/issues/3361326 missed a few things from this issue.

vladimiraus’s picture

Status: Needs review » Needs work

Please use merge request for easier review process. Thanks.

lisotton changed the visibility of the branch 2.0.x to hidden.

lisotton changed the visibility of the branch 2.x to hidden.

lisotton’s picture

Status: Needs work » Needs review

I have opened the MR.

vladimiraus’s picture

Status: Needs review » Reviewed & tested by the community

Thank you! Looks good. 🍻
RTBC

bdanin’s picture

Confirmed the MR fixes the issue for me as well.

VladimirAus changed the visibility of the branch 3308506-typehint-module-handler-interface to hidden.

rajivgandhi chinnakrishnan’s picture

StatusFileSize
new2.17 KB

Session limit 2.0.1 is getting conflicted with hook_event_subscriber module. This patch resolves the conflict.

fskreuz’s picture

The MR already covers the replacing of ModuleHandler to ModuleHandlerInterface, and more. Hiding this patch to avoid confusion.

jannakha’s picture

+1 RTBC

vladimiraus’s picture

Status: Reviewed & tested by the community » Fixed

Doneski! Thank you! 🥂

Status: Fixed » Closed (fixed)

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