Skip to content

Commit 7ce94f3

Browse files
author
Amrouche Hamza
committed
[HttpKernel] Add a better error messages when passing a private or non-tagged controller
1 parent 1f14f4d commit 7ce94f3

File tree

2 files changed

+69
-3
lines changed

2 files changed

+69
-3
lines changed

src/Symfony/Component/HttpKernel/Controller/ContainerControllerResolver.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
use Psr\Container\ContainerInterface;
1515
use Psr\Log\LoggerInterface;
16+
use Symfony\Component\Debug\Exception\FatalThrowableError;
17+
use Symfony\Component\DependencyInjection\Container;
1618
use Symfony\Component\HttpFoundation\Request;
1719

1820
/**
@@ -82,10 +84,24 @@ protected function createController($controller)
8284
*/
8385
protected function instantiateController($class)
8486
{
85-
if ($this->container->has($class)) {
86-
return $this->container->get($class);
87+
try {
88+
if ($this->container->has($class)) {
89+
return $this->container->get($class);
90+
}
91+
return parent::instantiateController($class);
92+
} catch (FatalThrowableError $e) {
93+
$this->throwWhenControllerIsNotInContainer($class);
94+
} catch (\ArgumentCountError $e) {
95+
$this->throwWhenControllerIsNotInContainer($class);
8796
}
97+
}
8898

89-
return parent::instantiateController($class);
99+
private function throwWhenControllerIsNotInContainer(string $class)
100+
{
101+
if ($this->container instanceof Container) {
102+
if (in_array($class, $this->container->getRemovedIds())) {
103+
throw new \InvalidArgumentException(sprintf('The controller %s seems to be removed from the container, which means that he maybe private, add the tag \'controller.service_arguments\' or made it public.', $class));
104+
}
105+
}
90106
}
91107
}

src/Symfony/Component/HttpKernel/Tests/Controller/ContainerControllerResolverTest.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Psr\Container\ContainerInterface;
1515
use Psr\Log\LoggerInterface;
16+
use Symfony\Component\DependencyInjection\ContainerBuilder;
1617
use Symfony\Component\HttpFoundation\Request;
1718
use Symfony\Component\HttpKernel\Controller\ContainerControllerResolver;
1819

@@ -106,6 +107,44 @@ public function testNonInstantiableController()
106107
$this->assertSame(array(NonInstantiableController::class, 'action'), $controller);
107108
}
108109

110+
public function testNonConstructController()
111+
{
112+
$container = $this->getMockBuilder(ContainerBuilder::class)->getMock();
113+
$container->expects($this->at(0))
114+
->method('has')
115+
->with(ImpossibleConstructController::class)
116+
->will($this->returnValue(true))
117+
;
118+
119+
$container->expects($this->at(1))
120+
->method('has')
121+
->with(ImpossibleConstructController::class)
122+
->will($this->returnValue(false))
123+
;
124+
125+
$container->expects($this->atLeastOnce())
126+
->method('getRemovedIds')
127+
->with()
128+
->will($this->returnValue([ImpossibleConstructController::class]))
129+
;
130+
131+
if (method_exists($this, 'expectException')) {
132+
$this->expectException(\InvalidArgumentException::class);
133+
$this->expectExceptionMessage('The controller Symfony\Component\HttpKernel\Tests\Controller\ImpossibleConstructController seems to be removed from the container, which means that he maybe private, add the tag \'controller.service_arguments\' or made it public.');
134+
} else {
135+
$this->setExpectedException(\InvalidArgumentException::class, 'The controller Symfony\Component\HttpKernel\Tests\Controller\ImpossibleConstructController seems to be removed from the container, which means that he maybe private, add the tag \'controller.service_arguments\' or made it public.');
136+
}
137+
138+
139+
$resolver = $this->createControllerResolver(null, $container);
140+
$request = Request::create('/');
141+
$request->attributes->set('_controller', array(ImpossibleConstructController::class, 'action'));
142+
143+
$controller = $resolver->getController($request);
144+
145+
$this->assertSame(array(ImpossibleConstructController::class, 'action'), $controller);
146+
}
147+
109148
public function testNonInstantiableControllerWithCorrespondingService()
110149
{
111150
$service = new \stdClass();
@@ -196,3 +235,14 @@ public static function action()
196235
{
197236
}
198237
}
238+
239+
class ImpossibleConstructController
240+
{
241+
public function __construct(string $toto, $controller)
242+
{
243+
}
244+
245+
public function action()
246+
{
247+
}
248+
}

0 commit comments

Comments
 (0)