Skip to content

Commit

Permalink
[DependencyInjection] Fix computing error messages involving service …
Browse files Browse the repository at this point in the history
…locators
  • Loading branch information
nicolas-grekas committed Feb 22, 2024
1 parent 45474d5 commit cc1fb23
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 19 deletions.
51 changes: 36 additions & 15 deletions Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ class CheckExceptionOnInvalidReferenceBehaviorPass extends AbstractRecursivePass
{
private $serviceLocatorContextIds = [];

/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
$this->serviceLocatorContextIds = [];
Expand Down Expand Up @@ -58,15 +55,7 @@ protected function processValue($value, bool $isRoot = false)
if (isset($this->serviceLocatorContextIds[$currentId])) {
$currentId = $this->serviceLocatorContextIds[$currentId];
$locator = $this->container->getDefinition($this->currentId)->getFactory()[0];

foreach ($locator->getArgument(0) as $k => $v) {
if ($v->getValues()[0] === $value) {
if ($k !== $id) {
$currentId = $k.'" in the container provided to "'.$currentId;
}
throw new ServiceNotFoundException($id, $currentId, null, $this->getAlternatives($id));
}
}
$this->throwServiceNotFoundException($value, $currentId, $locator->getArgument(0));
}

if ('.' === $currentId[0] && $graph->hasNode($currentId)) {
Expand All @@ -80,14 +69,21 @@ protected function processValue($value, bool $isRoot = false)
$currentId = $sourceId;
break;
}

if (isset($this->serviceLocatorContextIds[$sourceId])) {
$currentId = $this->serviceLocatorContextIds[$sourceId];
$locator = $this->container->getDefinition($this->currentId);
$this->throwServiceNotFoundException($value, $currentId, $locator->getArgument(0));
}
}
}

throw new ServiceNotFoundException($id, $currentId, null, $this->getAlternatives($id));
$this->throwServiceNotFoundException($value, $currentId, $value);
}

private function getAlternatives(string $id): array
private function throwServiceNotFoundException(Reference $ref, string $sourceId, $value): void
{
$id = (string) $ref;
$alternatives = [];
foreach ($this->container->getServiceIds() as $knownId) {
if ('' === $knownId || '.' === $knownId[0]) {
Expand All @@ -100,6 +96,31 @@ private function getAlternatives(string $id): array
}
}

return $alternatives;
$pass = new class() extends AbstractRecursivePass {
public $ref;
public $sourceId;
public $alternatives;

/**
* @return mixed
*/
public function processValue($value, bool $isRoot = false)
{
if ($this->ref !== $value) {
return parent::processValue($value, $isRoot);
}
$sourceId = $this->sourceId;
if (null !== $this->currentId && $this->currentId !== (string) $value) {
$sourceId = $this->currentId.'" in the container provided to "'.$sourceId;
}

throw new ServiceNotFoundException((string) $value, $sourceId, null, $this->alternatives);
}
};
$pass->ref = $ref;
$pass->sourceId = $sourceId;
$pass->alternatives = $alternatives;

$pass->processValue($value, true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ public function testProcessDefinitionWithBindings()
$this->addToAssertionCount(1);
}

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

(new AnalyzeServiceReferencesPass())->process($container);
(new InlineServiceDefinitionsPass())->process($container);
if ($inline) {
(new InlineServiceDefinitionsPass())->process($container);
}
$this->process($container);
}

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

(new AnalyzeServiceReferencesPass())->process($container);
(new InlineServiceDefinitionsPass())->process($container);
if ($inline) {
(new InlineServiceDefinitionsPass())->process($container);
}
$this->process($container);
}

Expand Down

0 comments on commit cc1fb23

Please sign in to comment.