bug #32040 [DI] Show the right class autowired when providing a non-existing class (Simperfit)
This PR was merged into the 4.3 branch.
Discussion
----------
[DI] Show the right class autowired when providing a non-existing class
| Q | A
| ------------- | ---
| Branch? 4.3
| Bug fix? | yes
| New feature? | no <!-- please update src/**/CHANGELOG.md files -->
| BC breaks? | no <!-- see https://symfony.com/bc -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass? | yes <!-- please add some, will be required by reviewers -->
| Fixed tickets | #31997 <!-- #-prefixed issue number(s), if any -->
| License | MIT
| Doc PR |none <!-- required for new features -->
<!--
Replace this notice by a short README for your feature/bugfix. This will help people
understand your PR and can be used as a start for the documentation.
Additionally (see https://symfony.com/roadmap):
- Bug fixes must be submitted against the lowest maintained branch where they apply
(lowest branches are regularly merged to upper ones so they get the fixes too).
- Features and deprecations must be submitted against branch 4.4.
- Legacy code removals go to the master branch.
-->
This gets the last current id before the error and pass it to the callback in order to get the right error message.
Commits
-------
fbda90af6e
[DI] Show the right class autowired when providing a non-existing class in constructor
This commit is contained in:
commit
db1543514e
@ -379,13 +379,14 @@ class AutowirePass extends AbstractRecursivePass
|
|||||||
$container->setAliases($this->container->getAliases());
|
$container->setAliases($this->container->getAliases());
|
||||||
$container->setDefinitions($this->container->getDefinitions());
|
$container->setDefinitions($this->container->getDefinitions());
|
||||||
$container->setResourceTracking(false);
|
$container->setResourceTracking(false);
|
||||||
|
$currentId = $this->currentId;
|
||||||
|
|
||||||
return function () use ($container, $reference, $label) {
|
return function () use ($container, $reference, $label, $currentId) {
|
||||||
return $this->createTypeNotFoundMessage($container, $reference, $label);
|
return $this->createTypeNotFoundMessage($container, $reference, $label, $currentId);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createTypeNotFoundMessage(ContainerBuilder $container, TypedReference $reference, $label)
|
private function createTypeNotFoundMessage(ContainerBuilder $container, TypedReference $reference, $label, string $currentId)
|
||||||
{
|
{
|
||||||
if (!$r = $container->getReflectionClass($type = $reference->getType(), false)) {
|
if (!$r = $container->getReflectionClass($type = $reference->getType(), false)) {
|
||||||
// either $type does not exist or a parent class does not exist
|
// either $type does not exist or a parent class does not exist
|
||||||
@ -409,7 +410,7 @@ class AutowirePass extends AbstractRecursivePass
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$message = sprintf('Cannot autowire service "%s": %s %s', $this->currentId, $label, $message);
|
$message = sprintf('Cannot autowire service "%s": %s %s', $currentId, $label, $message);
|
||||||
|
|
||||||
if (null !== $this->lastFailure) {
|
if (null !== $this->lastFailure) {
|
||||||
$message = $this->lastFailure."\n".$message;
|
$message = $this->lastFailure."\n".$message;
|
||||||
|
@ -50,6 +50,22 @@ class AutowirePassTest extends TestCase
|
|||||||
$this->assertEquals(Foo::class, (string) $container->getDefinition('bar')->getArgument(0));
|
$this->assertEquals(Foo::class, (string) $container->getDefinition('bar')->getArgument(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
|
||||||
|
* @expectedExceptionMessage Cannot autowire service "Symfony\Component\DependencyInjection\Tests\CompilerEslaAction": argument "$notExisting" of method "Symfony\Component\DependencyInjection\Tests\Compiler\ElsaAction::__construct()" has type "Symfony\Component\DependencyInjection\Tests\Compiler\NotExisting" but this class was not found.
|
||||||
|
*/
|
||||||
|
public function testProcessNotExistingActionParam()
|
||||||
|
{
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
|
||||||
|
$container->register(Foo::class);
|
||||||
|
$barDefinition = $container->register(__NAMESPACE__.'EslaAction', __NAMESPACE__.'\ElsaAction');
|
||||||
|
$barDefinition->setAutowired(true);
|
||||||
|
|
||||||
|
(new ResolveClassPass())->process($container);
|
||||||
|
(new AutowirePass())->process($container);
|
||||||
|
}
|
||||||
|
|
||||||
public function testProcessVariadic()
|
public function testProcessVariadic()
|
||||||
{
|
{
|
||||||
$container = new ContainerBuilder();
|
$container = new ContainerBuilder();
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
|
||||||
|
|
||||||
|
class ConstructNotExists
|
||||||
|
{
|
||||||
|
public function __construct(NotExist $notExist)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -419,3 +419,10 @@ class NonAutowirableDecorator implements DecoratorInterface
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class ElsaAction
|
||||||
|
{
|
||||||
|
public function __construct(NotExisting $notExisting)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
services:
|
||||||
|
_defaults:
|
||||||
|
public: true
|
||||||
|
autowire: true
|
||||||
|
autoconfigure: true
|
||||||
|
|
||||||
|
Symfony\Component\DependencyInjection\Tests\Fixtures\ConstructNotExists: ~
|
@ -804,6 +804,18 @@ class YamlFileLoaderTest extends TestCase
|
|||||||
], array_map(function (BoundArgument $v) { return $v->getValues()[0]; }, $definition->getBindings()));
|
], array_map(function (BoundArgument $v) { return $v->getValues()[0]; }, $definition->getBindings()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||||
|
* @expectedExceptionMessage Cannot autowire service "Symfony\Component\DependencyInjection\Tests\Fixtures\ConstructNotExists": argument "$notExist" of method "__construct()" has type "Symfony\Component\DependencyInjection\Tests\Fixtures\NotExist" but this class was not found.
|
||||||
|
*/
|
||||||
|
public function testProcessNotExistingActionParam()
|
||||||
|
{
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
|
||||||
|
$loader->load('services_not_existing.yml');
|
||||||
|
$container->compile();
|
||||||
|
}
|
||||||
|
|
||||||
public function testFqcnLazyProxy()
|
public function testFqcnLazyProxy()
|
||||||
{
|
{
|
||||||
$container = new ContainerBuilder();
|
$container = new ContainerBuilder();
|
||||||
|
Reference in New Issue
Block a user