8000 bug #54035 [DependencyInjection] Fix computing error messages involvi… · symfony/symfony@1a4748e · GitHub
[go: up one dir, main page]

Skip to content

Commit 1a4748e

Browse files
bug #54035 [DependencyInjection] Fix computing error messages involving service locators (nicolas-grekas)
This PR was merged into the 5.4 branch. Discussion ---------- [DependencyInjection] Fix computing error messages involving service locators | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no | Deprecations? |no | Issues | - | License | MIT I just realized that #39151 broke the logic in CheckExceptionOnInvalidReferenceBehaviorPass because it relied on inlining pass doing its job. This makes the pass work with and without inlining. Commits ------- ca7afaf [DependencyInjection] Fix computing error messages involving service locators
2 parents ecb2145 + ca7afaf commit 1a4748e

File tree

2 files changed

+52
-19
lines changed

2 files changed

+52
-19
lines changed

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

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ class CheckExceptionOnInvalidReferenceBehaviorPass extends AbstractRecursivePass
2525
{
2626
private $serviceLocatorContextIds = [];
2727

28-
/**
29-
* {@inheritdoc}
30-
*/
3128
public function process(ContainerBuilder $container)
3229
{
3330
$this->serviceLocatorContextIds = [];
@@ -58,15 +55,7 @@ protected function processValue($value, bool $isRoot = false)
5855
if (isset($this->serviceLocatorContextIds[$currentId])) {
5956
$currentId = $this->serviceLocatorContextIds[$currentId];
6057
$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-
}
58+
$this->throwServiceNotFoundException($value, $currentId, $locator->getArgument(0));
7059
}
7160

7261
if ('.' === $currentId[0] && $graph->hasNode($currentId)) {
@@ -80,14 +69,21 @@ protected function processValue($value, bool $isRoot = false)
8069
$currentId = $sourceId;
8170
break;
8271
}
72+
73+
if (isset($this->serviceLocatorContextIds[$sourceId])) {
74+
$currentId = $this->serviceLocatorContextIds[$sourceId];
75+
$locator = $this->container->getDefinition($this->currentId);
76+
$this->throwServiceNotFoundException($value, $currentId, $locator->getArgument(0));
77+
}
8378
}
8479
}
8580

86-
throw new ServiceNotFoundException($id, $currentId, null, $this->getAlternatives($id));
81+
$this->throwServiceNotFoundException($value, $currentId, $value);
8782
}
8883

89-
private function getAlternatives(string $id): array
84+
private function throwServiceNotFoundException(Reference $ref, string $sourceId, $value): void
9085
{
86+
$id = (string) $ref;
9187
$alternatives = [];
9288
foreach ($this->container->getServiceIds() as $knownId) {
9389
if ('' === $knownId || '.' === $knownId[0]) {
@@ -100,6 +96,31 @@ private function getAlternatives(string $id): array
10096
}
10197
}
10298

103-
return $alternatives;
99+
$pass = new class() extends AbstractRecursivePass {
100+
public $ref;
101+
public $sourceId;
102+
public $alternatives;
103+
104+
/**
105+
* @return mixed
106+
*/
107+
public function processValue($value, bool $isRoot = false)
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)
0