Skip to content

Commit 35ac8cd

Browse files
[DI] Fix AutowirePass fatal error with classes that have non-existing parents
1 parent b0c42fb commit 35ac8cd

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

Compiler/AutowirePass.php

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,32 @@ class AutowirePass implements CompilerPassInterface
3434
*/
3535
public function process(ContainerBuilder $container)
3636
{
37-
$this->container = $container;
38-
foreach ($container->getDefinitions() as $id => $definition) {
39-
if ($definition->isAutowired()) {
40-
$this->completeDefinition($id, $definition);
37+
$throwingAutoloader = function ($class) { throw new \ReflectionException(sprintf('Class %s does not exist', $class)); };
38+
spl_autoload_register($throwingAutoloader);
39+
40+
try {
41+
$this->container = $container;
42+
foreach ($container->getDefinitions() as $id => $definition) {
43+
if ($definition->isAutowired()) {
44+
$this->completeDefinition($id, $definition);
45+
}
4146
}
47+
} catch (\Error $e) {
48+
} catch (\Exception $e) {
4249
}
4350

51+
spl_autoload_unregister($throwingAutoloader);
52+
4453
// Free memory and remove circular reference to container
4554
$this->container = null;
4655
$this->reflectionClasses = array();
4756
$this->definedTypes = array();
4857
$this->types = null;
4958
$this->notGuessableTypes = array();
59+
60+
if (isset($e)) {
61+
throw $e;
62+
}
5063
}
5164

5265
/**
@@ -107,11 +120,11 @@ private function completeDefinition($id, Definition $definition)
107120
}
108121
}
109122
}
110-
} catch (\ReflectionException $reflectionException) {
123+
} catch (\ReflectionException $e) {
111124
// Typehint against a non-existing class
112125

113126
if (!$parameter->isDefaultValueAvailable()) {
114-
throw new RuntimeException(sprintf('Cannot autowire argument %s for %s because the type-hinted class does not exist (%s).', $index + 1, $definition->getClass(), $reflectionException->getMessage()), 0, $reflectionException);
127+
throw new RuntimeException(sprintf('Cannot autowire argument %s for %s because the type-hinted class does not exist (%s).', $index + 1, $definition->getClass(), $e->getMessage()), 0, $e);
115128
}
116129

117130
$value = $parameter->getDefaultValue();
@@ -245,7 +258,7 @@ private function getReflectionClass($id, Definition $definition)
245258

246259
try {
247260
$reflector = new \ReflectionClass($class);
248-
} catch (\ReflectionException $reflectionException) {
261+
} catch (\ReflectionException $e) {
249262
$reflector = false;
250263
}
251264

Tests/Compiler/AutowirePassTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,21 @@ public function testClassNotFoundThrowsException()
268268
$pass->process($container);
269269
}
270270

271+
/**
272+
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
273+
* @expectedExceptionMessage Cannot autowire argument 2 for Symfony\Component\DependencyInjection\Tests\Compiler\BadParentTypeHintedArgument because the type-hinted class does not exist (Class Symfony\Component\DependencyInjection\Tests\Compiler\OptionalServiceClass does not exist).
274+
*/
275+
public function testParentClassNotFoundThrowsException()
276+
{
277+
$container = new ContainerBuilder();
278+
279+
$aDefinition = $container->register('a', __NAMESPACE__.'\BadParentTypeHintedArgument');
280+
$aDefinition->setAutowired(true);
281+
282+
$pass = new AutowirePass();
283+
$pass->process($container);
284+
}
285+
271286
public function testDontUseAbstractServices()
272287
{
273288
$container = new ContainerBuilder();
@@ -524,6 +539,12 @@ public function __construct(Dunglas $k, NotARealClass $r)
524539
{
525540
}
526541
}
542+
class BadParentTypeHintedArgument
543+
{
544+
public function __construct(Dunglas $k, OptionalServiceClass $r)
545+
{
546+
}
547+
}
527548
class NotGuessableArgument
528549
{
529550
public function __construct(Foo $k)

0 commit comments

Comments
 (0)