minor #22326 [DI] Enhance wording of autowiring exceptions (nicolas-grekas)
This PR was merged into the 3.3-dev branch.
Discussion
----------
[DI] Enhance wording of autowiring exceptions
| Q | A
| ------------- | ---
| Branch? | 3.3
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
> Cannot autowire service "j": argument "$i" of method "Symfony\Component\DependencyInjection\Tests\Compiler\J::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\I" but no such service exists. You should maybe alias this class to the existing "i" service; or type-hint against interface "Symfony\Component\DependencyInjection\Tests\Compiler\IInterface" instead.
Commits
-------
da792b2ff7
[DI] Enhance wording of autowiring exceptions
This commit is contained in:
commit
49ae724e9c
@ -439,27 +439,30 @@ class AutowirePass extends AbstractRecursivePass
|
|||||||
|
|
||||||
private function createTypeAlternatives($type)
|
private function createTypeAlternatives($type)
|
||||||
{
|
{
|
||||||
$message = ' This type-hint could be aliased to ';
|
|
||||||
|
|
||||||
if (isset($this->ambiguousServiceTypes[$type])) {
|
if (isset($this->ambiguousServiceTypes[$type])) {
|
||||||
$message .= sprintf('one of these existing services: "%s"', implode('", "', $this->ambiguousServiceTypes[$type]));
|
$message = sprintf('one of these existing services: "%s"', implode('", "', $this->ambiguousServiceTypes[$type]));
|
||||||
} elseif (isset($this->types[$type])) {
|
} elseif (isset($this->types[$type])) {
|
||||||
$message .= sprintf('the existing "%s" service', $this->types[$type]);
|
$message = sprintf('the existing "%s" service', $this->types[$type]);
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
$message = sprintf(' You should maybe alias this %s to %s', class_exists($type, false) ? 'class' : 'interface', $message);
|
||||||
$aliases = array();
|
$aliases = array();
|
||||||
|
|
||||||
foreach (class_parents($type) + class_implements($type) as $parent) {
|
foreach (class_parents($type) + class_implements($type) as $parent) {
|
||||||
if ($this->container->has($parent)) {
|
if ($this->container->has($parent) && !$this->container->findDefinition($parent)->isAbstract()) {
|
||||||
$aliases[] = $parent;
|
$aliases[] = $parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (1 < count($aliases)) {
|
if (1 < $len = count($aliases)) {
|
||||||
$message .= sprintf('; or be updated to one of the following: "%s"', implode('", "', $aliases));
|
$message .= '; or type-hint against one of its parents: ';
|
||||||
|
for ($i = 0, --$len; $i < $len; ++$i) {
|
||||||
|
$message .= sprintf('%s "%s", ', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]);
|
||||||
|
}
|
||||||
|
$message .= sprintf('or %s "%s"', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]);
|
||||||
} elseif ($aliases) {
|
} elseif ($aliases) {
|
||||||
$message .= sprintf('; or be updated to "%s"', $aliases[0]);
|
$message .= sprintf('; or type-hint against %s "%s" instead', class_exists($aliases[0], false) ? 'class' : 'interface', $aliases[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $message.'.';
|
return $message.'.';
|
||||||
|
@ -59,7 +59,7 @@ class AutowirePassTest extends TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||||
* @expectedExceptionMessage Cannot autowire service "c": argument "$a" of method "Symfony\Component\DependencyInjection\Tests\Compiler\C::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\A" but no such service exists. This type-hint could be aliased to the existing "Symfony\Component\DependencyInjection\Tests\Compiler\B" service.
|
* @expectedExceptionMessage Cannot autowire service "c": argument "$a" of method "Symfony\Component\DependencyInjection\Tests\Compiler\C::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\A" but no such service exists. You should maybe alias this class to the existing "Symfony\Component\DependencyInjection\Tests\Compiler\B" service.
|
||||||
*/
|
*/
|
||||||
public function testProcessAutowireParent()
|
public function testProcessAutowireParent()
|
||||||
{
|
{
|
||||||
@ -78,7 +78,7 @@ class AutowirePassTest extends TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||||
* @expectedExceptionMessage Cannot autowire service "g": argument "$d" of method "Symfony\Component\DependencyInjection\Tests\Compiler\G::__construct()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\DInterface" but no such service exists. This type-hint could be aliased to the existing "Symfony\Component\DependencyInjection\Tests\Compiler\F" service.
|
* @expectedExceptionMessage Cannot autowire service "g": argument "$d" of method "Symfony\Component\DependencyInjection\Tests\Compiler\G::__construct()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\DInterface" but no such service exists. You should maybe alias this interface to the existing "Symfony\Component\DependencyInjection\Tests\Compiler\F" service.
|
||||||
*/
|
*/
|
||||||
public function testProcessAutowireInterface()
|
public function testProcessAutowireInterface()
|
||||||
{
|
{
|
||||||
@ -133,7 +133,7 @@ class AutowirePassTest extends TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||||
* @expectedExceptionMessage Cannot autowire service "a": argument "$collision" of method "Symfony\Component\DependencyInjection\Tests\Compiler\CannotBeAutowired::__construct()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" but no such service exists. This type-hint could be aliased to one of these existing services: "c1", "c2", "c3".
|
* @expectedExceptionMessage Cannot autowire service "a": argument "$collision" of method "Symfony\Component\DependencyInjection\Tests\Compiler\CannotBeAutowired::__construct()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "c1", "c2", "c3".
|
||||||
*/
|
*/
|
||||||
public function testTypeCollision()
|
public function testTypeCollision()
|
||||||
{
|
{
|
||||||
@ -151,7 +151,7 @@ class AutowirePassTest extends TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||||
* @expectedExceptionMessage Cannot autowire service "a": argument "$k" of method "Symfony\Component\DependencyInjection\Tests\Compiler\NotGuessableArgument::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" but no such service exists. This type-hint could be aliased to one of these existing services: "a1", "a2".
|
* @expectedExceptionMessage Cannot autowire service "a": argument "$k" of method "Symfony\Component\DependencyInjection\Tests\Compiler\NotGuessableArgument::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" but no such service exists. You should maybe alias this class to one of these existing services: "a1", "a2".
|
||||||
*/
|
*/
|
||||||
public function testTypeNotGuessable()
|
public function testTypeNotGuessable()
|
||||||
{
|
{
|
||||||
@ -168,7 +168,7 @@ class AutowirePassTest extends TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||||
* @expectedExceptionMessage Cannot autowire service "a": argument "$k" of method "Symfony\Component\DependencyInjection\Tests\Compiler\NotGuessableArgumentForSubclass::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\A" but no such service exists. This type-hint could be aliased to one of these existing services: "a1", "a2".
|
* @expectedExceptionMessage Cannot autowire service "a": argument "$k" of method "Symfony\Component\DependencyInjection\Tests\Compiler\NotGuessableArgumentForSubclass::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\A" but no such service exists. You should maybe alias this class to one of these existing services: "a1", "a2".
|
||||||
*/
|
*/
|
||||||
public function testTypeNotGuessableWithSubclass()
|
public function testTypeNotGuessableWithSubclass()
|
||||||
{
|
{
|
||||||
@ -334,7 +334,7 @@ class AutowirePassTest extends TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||||
* @expectedExceptionMessage Cannot autowire service "bar": argument "$foo" of method "Symfony\Component\DependencyInjection\Tests\Compiler\Bar::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" but this service is abstract. This type-hint could be aliased to the existing "foo" service.
|
* @expectedExceptionMessage Cannot autowire service "bar": argument "$foo" of method "Symfony\Component\DependencyInjection\Tests\Compiler\Bar::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" but this service is abstract. You should maybe alias this class to the existing "foo" service.
|
||||||
*/
|
*/
|
||||||
public function testDontUseAbstractServices()
|
public function testDontUseAbstractServices()
|
||||||
{
|
{
|
||||||
@ -587,7 +587,7 @@ class AutowirePassTest extends TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||||
* @expectedExceptionMessage Cannot autowire service "setter_injection_collision": argument "$collision" of method "Symfony\Component\DependencyInjection\Tests\Compiler\SetterInjectionCollision::setMultipleInstancesForOneArg()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" but no such service exists. This type-hint could be aliased to one of these existing services: "c1", "c2".
|
* @expectedExceptionMessage Cannot autowire service "setter_injection_collision": argument "$collision" of method "Symfony\Component\DependencyInjection\Tests\Compiler\SetterInjectionCollision::setMultipleInstancesForOneArg()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "c1", "c2".
|
||||||
*/
|
*/
|
||||||
public function testSetterInjectionCollisionThrowsException()
|
public function testSetterInjectionCollisionThrowsException()
|
||||||
{
|
{
|
||||||
@ -604,7 +604,7 @@ class AutowirePassTest extends TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||||
* @expectedExceptionMessage Cannot autowire service "bar": argument "$foo" of method "Symfony\Component\DependencyInjection\Tests\Compiler\Bar::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" but no such service exists. This type-hint could be aliased to the existing "foo" service.
|
* @expectedExceptionMessage Cannot autowire service "bar": argument "$foo" of method "Symfony\Component\DependencyInjection\Tests\Compiler\Bar::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" but no such service exists. You should maybe alias this class to the existing "foo" service.
|
||||||
*/
|
*/
|
||||||
public function testProcessDoesNotTriggerDeprecations()
|
public function testProcessDoesNotTriggerDeprecations()
|
||||||
{
|
{
|
||||||
@ -688,7 +688,7 @@ class AutowirePassTest extends TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||||
* @expectedExceptionMessage Cannot autowire service "j": argument "$i" of method "Symfony\Component\DependencyInjection\Tests\Compiler\J::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\I" but no such service exists. This type-hint could be aliased to the existing "i" service; or be updated to "Symfony\Component\DependencyInjection\Tests\Compiler\IInterface".
|
* @expectedExceptionMessage Cannot autowire service "j": argument "$i" of method "Symfony\Component\DependencyInjection\Tests\Compiler\J::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\I" but no such service exists. You should maybe alias this class to the existing "i" service; or type-hint against interface "Symfony\Component\DependencyInjection\Tests\Compiler\IInterface" instead.
|
||||||
*/
|
*/
|
||||||
public function testByIdAlternative()
|
public function testByIdAlternative()
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user