Skip to content

Commit

Permalink
[HttpKernel] Add a better error messages when passing a private or no…
Browse files Browse the repository at this point in the history
…n-tagged controller
  • Loading branch information
Amrouche Hamza committed Nov 30, 2017
1 parent 1f14f4d commit f5709c5
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
Expand Up @@ -13,6 +13,8 @@

use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Debug\Exception\FatalThrowableError;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\HttpFoundation\Request;

/**
Expand Down Expand Up @@ -86,6 +88,16 @@ protected function instantiateController($class)
return $this->container->get($class);
}

return parent::instantiateController($class);
try {
return parent::instantiateController($class);
} catch (FatalThrowableError $e) {
} catch (\ArgumentCountError $e) {
}

if ($this->container instanceof Container && in_array($class, $this->container->getRemovedIds(), true)) {
throw new \LogicException(sprintf('Controller "%s" cannot be fetched from the container because it is private. Did you forget to tag the service with "controller.service_arguments"?', $class), 0, $e);
}

throw $e;
}
}
Expand Up @@ -13,6 +13,9 @@

use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Debug\ErrorHandler;
use Symfony\Component\Debug\Exception\ContextErrorException;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ContainerControllerResolver;

Expand Down Expand Up @@ -106,6 +109,48 @@ public function testNonInstantiableController()
$this->assertSame(array(NonInstantiableController::class, 'action'), $controller);
}

/**
* @expectedException \LogicException
* @expectedExceptionMessage Controller "Symfony\Component\HttpKernel\Tests\Controller\ImpossibleConstructController" cannot be fetched from the container because it is private. Did you forget to tag the service with "controller.service_arguments"?
*/
public function testNonConstructController()
{
$container = $this->getMockBuilder(Container::class)->getMock();
$container->expects($this->at(0))
->method('has')
->with(ImpossibleConstructController::class)
->will($this->returnValue(true))
;

$container->expects($this->at(1))
->method('has')
->with(ImpossibleConstructController::class)
->will($this->returnValue(false))
;

$container->expects($this->atLeastOnce())
->method('getRemovedIds')
->with()
->will($this->returnValue(array(ImpossibleConstructController::class)))
;

$resolver = $this->createControllerResolver(null, $container);
$request = Request::create('/');
$request->attributes->set('_controller', array(ImpossibleConstructController::class, 'action'));

if (\PHP_VERSION_ID < 70000) {
ErrorHandler::register();
try {
$resolver->getController($request);
} finally {
restore_error_handler();
restore_exception_handler();
}
} else {
$resolver->getController($request);
}
}

public function testNonInstantiableControllerWithCorrespondingService()
{
$service = new \stdClass();
Expand Down Expand Up @@ -196,3 +241,14 @@ public static function action()
{
}
}

class ImpossibleConstructController
{
public function __construct($toto, $controller)
{
}

public function action()
{
}
}

0 comments on commit f5709c5

Please sign in to comment.