Skip to content

Commit 0c1e19f

Browse files
[DependencyInjection] Fix computing error messages involving service locators
1 parent 526bb8b commit 0c1e19f

File tree

2 files changed

+49
-16
lines changed

2 files changed

+49
-16
lines changed

src/Symfony/Component/DependencyInjection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,7 @@ protected function processValue($value, bool $isRoot = false)
5858
if (isset($this->serviceLocatorContextIds[$currentId])) {
5959
$currentId = $this->serviceLocatorContextIds[$currentId];
6060
$locator = $this->container->getDefinition($this->currentId)->getFactory()[0];
61-
62-
foreach ($locator->getArgument(0) as $k => $v) {
63-
if ($v->getValues()[0] === $value) {
64-
if ($k !== $id) {
65-
$currentId = $k.'" in the container provided to "'.$currentId;
66-
}
67-
throw new ServiceNotFoundException($id, $currentId, null, $this->getAlternatives($id));
68-
}
69-
}
61+
$this->throwServiceNotFoundException($value, $currentId, $locator->getArgument(0));
7062
}
7163

7264
if ('.' === $currentId[0] && $graph->hasNode($currentId)) {
@@ -80,14 +72,21 @@ protected function processValue($value, bool $isRoot = false)
8072
$currentId = $sourceId;
8173
break;
8274
}
75+
76+
if (isset($this->serviceLocatorContextIds[$sourceId])) {
77+
$currentId = $this->serviceLocatorContextIds[$sourceId];
78+
$locator = $this->container->getDefinition($this->currentId);
79+
$this->throwServiceNotFoundException($value, $currentId, $locator->getArgument(0));
80+
}
8381
}
8482
}
8583

86-
throw new ServiceNotFoundException($id, $currentId, null, $this->getAlternatives($id));
84+
$this->throwServiceNotFoundException($value, $currentId, $value);
8785
}
8886

89-
private function getAlternatives(string $id): array
87+
private function throwServiceNotFoundException(Reference $ref, string $sourceId, mixed $value): void
9088
{
89+
$id = (string) $ref;
9190
$alternatives = [];
9291
foreach ($this->container->getServiceIds() as $knownId) {
9392
if ('' === $knownId || '.' === $knownId[0]) {
@@ -100,6 +99,28 @@ private function getAlternatives(string $id): array
10099
}
101100
}
102101

103-
return $alternatives;
102+
$pass = new class($ref, $sourceId, $alternatives) extends AbstractRecursivePass {
103+
public $ref;
104+
public $sourceId;
105+
public $alternatives;
106+
107+
public function processValue(mixed $value, bool $isRoot = false): mixed
108+
{
109+
if ($this->ref !== $value) {
110+
return parent::processValue($value, $isRoot);
111+
}
112+
$sourceId = $this->sourceId;
113+
if (null !== $this->currentId && $this->currentId !== (string) $value) {
114+
$sourceId = $this->currentId.'" in the container provided to "'.$sourceId;
115+
}
116+
117+
throw new ServiceNotFoundException((string) $value, $sourceId, null, $this->alternatives);
118+
}
119+
};
120+
$pass->ref = $ref;
121+
$pass->sourceId = $sourceId;
122+
$pass->alternatives = $alternatives;
123+
124+
$pass->processValue($value, true);
104125
}
105126
}

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@ public function testProcessDefinitionWithBindings()
8282
$this->addToAssertionCount(1);
8383
}
8484

85-
public function testWithErroredServiceLocator()
85+
/**
86+
* @testWith [true]
87+
* [false]
88+
*/
89+
public function testWithErroredServiceLocator(bool $inline)
8690
{
8791
$this->expectException(ServiceNotFoundException::class);
8892
$this->expectExceptionMessage('The service "foo" in the container provided to "bar" has a dependency on a non-existent service "baz".');
@@ -91,11 +95,17 @@ public function testWithErroredServiceLocator()
9195
ServiceLocatorTagPass::register($container, ['foo' => new Reference('baz')], 'bar');
9296

9397
(new AnalyzeServiceReferencesPass())->process($container);
94-
(new InlineServiceDefinitionsPass())->process($container);
98+
if ($inline) {
99+
(new InlineServiceDefinitionsPass())->process($container);
100+
}
95101
$this->process($container);
96102
}
97103

98-
public function testWithErroredHiddenService()
104+
/**
105+
* @testWith [true]
106+
* [false]
107+
*/
108+
public function testWithErroredHiddenService(bool $inline)
99109
{
100110
$this->expectException(ServiceNotFoundException::class);
101111
$this->expectExceptionMessage('The service "bar" has a dependency on a non-existent service "foo".');
@@ -104,7 +114,9 @@ public function testWithErroredHiddenService()
104114
ServiceLocatorTagPass::register($container, ['foo' => new Reference('foo')], 'bar');
105115

106116
(new AnalyzeServiceReferencesPass())->process($container);
107-
(new InlineServiceDefinitionsPass())->process($container);
117+
if ($inline) {
118+
(new InlineServiceDefinitionsPass())->process($container);
119+
}
108120
$this->process($container);
109121
}
110122

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy