Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ca5930b

Browse files
committed
bug #18600 [DI] Fix AutowirePass fatal error with classes that have non-existing parents (hason, nicolas-grekas)
This PR was merged into the 2.8 branch. Discussion ---------- [DI] Fix AutowirePass fatal error with classes that have non-existing parents | Q | A | ------------- | --- | Branch? | 2.8 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #18188 | License | MIT | Doc PR | - Commits ------- 202cc77 [DI] Fix AutowirePass fatal error with classes that have non-existing parents 1735b85 [DependencyInjection] Tests for AutowirePass with missing parent class
2 parents 68415ab + 202cc77 commit ca5930b

File tree

3 files changed

+74
-7
lines changed

3 files changed

+74
-7
lines changed

src/Symfony/Component/DependencyInjection/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

src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php

Lines changed: 36 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();
@@ -397,6 +412,21 @@ public function testOptionalScalarArgsNotPassedIfLast()
397412
$definition->getArguments()
398413
);
399414
}
415+
416+
public function testIgnoreServiceWithClassNotExisting()
417+
{
418+
$container = new ContainerBuilder();
419+
420+
$container->register('class_not_exist', __NAMESPACE__.'\OptionalServiceClass');
421+
422+
$barDefinition = $container->register('bar', __NAMESPACE__.'\Bar');
423+
$barDefinition->setAutowired(true);
424+
425+
$pass = new AutowirePass();
426+
$pass->process($container);
427+
428+
$this->assertTrue($container->hasDefinition('bar'));
429+
}
400430
}
401431

402432
class Foo
@@ -509,6 +539,12 @@ public function __construct(Dunglas $k, NotARealClass $r)
509539
{
510540
}
511541
}
542+
class BadParentTypeHintedArgument
543+
{
544+
public function __construct(Dunglas $k, OptionalServiceClass $r)
545+
{
546+
}
547+
}
512548
class NotGuessableArgument
513549
{
514550
public function __construct(Foo $k)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
13+
14+
use Symfony\Bug\NotExistClass;
15+
16+
class OptionalServiceClass extends NotExistClass
17+
{
18+
}

0 commit comments

Comments
 (0)