Skip to content

Commit 2d29a78

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

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

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

Lines changed: 13 additions & 1 deletion
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
/**
@@ -86,6 +88,16 @@ protected function instantiateController($class)
8688
return $this->container->get($class);
8789
}
8890

89-
return parent::instantiateController($class);
91+
$e = null;
92+
93+
try {
94+
return parent::instantiateController($class);
95+
} catch (FatalThrowableError $e) {
96+
} catch (\ArgumentCountError $e) {
97+
}
98+
99+
if ($this->container instanceof Container && in_array($class, $this->container->getRemovedIds())) {
100+
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);
101+
}
90102
}
91103
}

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

Lines changed: 44 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,38 @@ public function testNonInstantiableController()
106107
$this->assertSame(array(NonInstantiableController::class, 'action'), $controller);
107108
}
108109

110+
/**
111+
* @expectedException \LogicException
112+
* @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"?
113+
*/
114+
public function testNonConstructController()
115+
{
116+
$container = $this->getMockBuilder(ContainerBuilder::class)->getMock();
117+
$container->expects($this->at(0))
118+
->method('has')
119+
->with(ImpossibleConstructController::class)
120+
->will($this->returnValue(true))
121+
;
122+
123+
$container->expects($this->at(1))
124+
->method('has')
125+
->with(ImpossibleConstructController::class)
126+
->will($this->returnValue(false))
127+
;
128+
129+
$container->expects($this->atLeastOnce())
130+
->method('getRemovedIds')
131+
->with()
132+
->will($this->returnValue(array(ImpossibleConstructController::class)))
133+
;
134+
135+
$resolver = $this->createControllerResolver(null, $container);
136+
$request = Request::create('/');
137+
$request->attributes->set('_controller', array(ImpossibleConstructController::class, 'action'));
138+
139+
$resolver->getController($request);
140+
}
141+
109142
public function testNonInstantiableControllerWithCorrespondingService()
110143
{
111144
$service = new \stdClass();
@@ -196,3 +229,14 @@ public static function action()
196229
{
197230
}
198231
}
232+
233+
class ImpossibleConstructController
234+
{
235+
public function __construct($toto, $controller)
236+
{
237+
}
238+
239+
public function action()
240+
{
241+
}
242+
}

0 commit comments

Comments
 (0)