Skip to content

Commit

Permalink
bug #32040 [DI] Show the right class autowired when providing a non-e…
Browse files Browse the repository at this point in the history
…xisting 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
-------

fbda90a [DI] Show the right class autowired when providing a non-existing class in constructor
  • Loading branch information
fabpot committed Jun 16, 2019
2 parents a9bcdcc + fbda90a commit db15435
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -379,13 +379,14 @@ private function createTypeNotFoundMessageCallback(TypedReference $reference, $l
$container->setAliases($this->container->getAliases());
$container->setDefinitions($this->container->getDefinitions());
$container->setResourceTracking(false);
$currentId = $this->currentId;

return function () use ($container, $reference, $label) {
return $this->createTypeNotFoundMessage($container, $reference, $label);
return function () use ($container, $reference, $label, $currentId) {
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)) {
// either $type does not exist or a parent class does not exist
Expand All @@ -409,7 +410,7 @@ private function createTypeNotFoundMessage(ContainerBuilder $container, TypedRef
}
}

$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) {
$message = $this->lastFailure."\n".$message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,22 @@ public function testProcess()
$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()
{
$container = new ContainerBuilder();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Symfony\Component\DependencyInjection\Tests\Fixtures;

class ConstructNotExists
{
public function __construct(NotExist $notExist)
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -419,3 +419,10 @@ public function __construct(LoggerInterface $logger, DecoratorInterface $decorat
{
}
}

final class ElsaAction
{
public function __construct(NotExisting $notExisting)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
services:
_defaults:
public: true
autowire: true
autoconfigure: true

Symfony\Component\DependencyInjection\Tests\Fixtures\ConstructNotExists: ~
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,18 @@ public function testBindings()
], 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()
{
$container = new ContainerBuilder();
Expand Down

0 comments on commit db15435

Please sign in to comment.