Problem/Motivation
I have a test module. When clearing the cache (calling drupal_flush_all_caches()), even when nate_test is disabled, I'm getting a ReflectionException. I have spent quite a bit of time trying to debug this. It doesn't happen locally on my mac, but it happens on a remote PC and on a linux server. If I enable the nate_test module, the error goes away. But if I disable the module, I get the error. I'd like to remove the module from my production server. I suspect there is a bug in EntityResolverManager.
The website encountered an unexpected error. Please try again later.
ReflectionException: Class \Drupal\nate_test\Controller\NateTestController does not exist in ReflectionMethod->__construct() (line 123 of core/lib/Drupal/Core/Entity/EntityResolverManager.php).
Drupal\Core\Entity\EntityResolverManager->setParametersFromReflection() (Line: 208)
Drupal\Core\Entity\EntityResolverManager->setRouteOptions() (Line: 48)
Drupal\Core\EventSubscriber\EntityRouteAlterSubscriber->onRoutingRouteAlterSetType()
call_user_func() (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch() (Line: 189)
Drupal\Core\Routing\RouteBuilder->rebuild() (Line: 83)
Drupal\Core\ProxyClass\Routing\RouteBuilder->rebuild() (Line: 578)
drupal_flush_all_caches() (Line: 192)
Steps to reproduce
My routing.yml:
nate_test.main:
path: '/nate-test'
defaults:
_controller: '\Drupal\nate_test\Controller\NateTestController::main'
_title: 'main'
requirements:
_permission: 'access content'
options:
no_cache: 'TRUE'
my controller:
<?php
namespace Drupal\nate_test\Controller;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Database\Driver\mysql\Connection;
/**
* Class NateTestController.
*
* @codeCoverageIgnore
*/
class NateTestController extends ControllerBase {
/**
* Drupal\Core\Entity\EntityTypeManagerInterface definition.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Drupal\Core\Database\Driver\mysql\Connection definition.
*
* @var \Drupal\Core\Database\Driver\mysql\Connection
*/
protected $database;
protected $container;
/**
* Constructs a new NateTestController object.
*
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, Connection $database) {
$this->entityTypeManager = $entity_type_manager;
$this->database = $database;
}
/**
* {@inheritdoc}
*
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager'),
$container->get('database')
);
}
/**
* Main.
*
* @return string
* Return Hello string.
*
*/
public function main() {
return ['#markup' => 'test'];
}
}
Proposed resolution
I think we could add a try catch, as handling the exception shouldn't break anything if the class doesn't exist:
$result = FALSE;
try {
if (is_array($controller)) {
list($instance, $method) = $controller;
$reflection = new \ReflectionMethod($instance, $method);
}
else {
$reflection = new \ReflectionFunction($controller);
}
}
catch (\Exception $e) {
return $result;
}
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet