8000 feature #22323 [DI] Report cascades of autowiring error messages (nic… · symfony/symfony@3458edf · GitHub
[go: up one dir, main page]

Skip to content

Commit 3458edf

Browse files
committed
feature #22323 [DI] Report cascades of autowiring error messages (nicolas-grekas)
This PR was merged into the 3.3-dev branch. Discussion ---------- [DI] Report cascades of autowiring error messages | Q | A | ------------- | --- | Branch? | 3.3 | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - Enhance DX by reporting the cascade of errors that lead to an autowiring error, eg: ![capture du 2017-04-07 00-03-28](https://cloud.githubusercontent.com/assets/243674/24777441/ac1fb118-1b25-11e7-9459-ecdf13e79798.png) Also contains a cleanup found along the way: processing of nested definitions should happen before the current one so that TypedReference are processed only once. Commits ------- 6c0f5e3 [DI] Reporte cascades of autowiring error messages
2 parents 451c32a + 6c0f5e3 commit 3458edf

File tree

1 file changed

+23
-16
lines changed

1 file changed

+23
-16
lines changed

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

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class AutowirePass extends AbstractRecursivePass
3030
private $types;
3131
private $ambiguousServiceTypes = array();
3232
private $autowired = array();
33+
private $lastFailure;
3334

3435
/**
3536
* {@inheritdoc}
@@ -77,21 +78,19 @@ protected function processValue($value, $isRoot = false)
7778
{
7879
if ($value instanceof TypedReference) {
7980
if ($ref = $this->getAutowiredReference($value)) {
80-
$value = $ref;
81-
} else {
82-
$this->container->log($this, $this->createTypeNotFoundMessage($value->getType(), 'typed reference'));
81+
return $ref;
8382
}
83+
$this->container->log($this, $this->createTypeNotFoundMessage($value->getType(), 'it'));
8484
}
85-
if (!$value instanceof Definition) {
86-
return parent::processValue($value, $isRoot);
87-
}
88-
if (!$value->isAutowired() || $value->isAbstract() || !$value->getClass()) {
89-
return parent::processValue($value, $isRoot);
85+
$value = parent::processValue($value, $isRoot);
86+
87+
if (!$value instanceof Definition || !$value->isAutowired() || $value->isAbstract() || !$value->getClass()) {
88+
return $value;
9089
}
9190
if (!$reflectionClass = $this->container->getReflectionClass($value->getClass())) {
9291
$this->container->log($this, sprintf('Skipping service "%s": Class or interface "%s" does not exist.', $this->currentId, $value->getClass()));
9392

94-
return parent::processValue($value, $isRoot);
93+
return $value;
9594
}
9695

9796
$autowiredMethods = $this->getMethodsToAutowire($reflectionClass);
@@ -115,7 +114,7 @@ protected function processValue($value, $isRoot = false)
115114
$value->setMethodCalls($methodCalls);
116115
}
117116

118-
return parent::processValue($value, $isRoot);
117+
return $value;
119118
}
120119

121120
/**
@@ -246,9 +245,7 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
246245

247246
if ($parameter->isDefaultValueAvailable()) {
248247
$value = $parameter->getDefaultValue();
249-
} elseif ($parameter->allowsNull()) {
250-
$value = null;
251-
} else {
248+
} elseif (!$parameter->allowsNull()) {
252249
throw new RuntimeException($failureMessage);
253250
}
254251
$this->container->log($this, $failureMessage);
@@ -279,6 +276,7 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
279276
*/
280277
private function getAutowiredReference(TypedReference $reference)
281278
{
279+
$this->lastFailure = null;
282280
$type = $reference->getType();
283281

284282
if ($type !== (string) $reference || ($this->container->has($type) && !$this->container->findDefinition($type)->isAbstract())) {
@@ -396,7 +394,8 @@ private function createAutowiredDefinition($type)
396394
}
397395

398396
$currentId = $this->currentId;
399-
$this->currentId = $this->autowired[$type] = $argumentId = sprintf('autowired.%s', $type);
397+
$this->currentId = $type;
398+
$this->autowired[$type] = $argumentId = sprintf('autowired.%s', $type);
400399
$argumentDefinition = new Definition($type);
401400
$argumentDefinition->setPublic(false);
402401
$argumentDefinition->setAutowired(true);
@@ -406,7 +405,8 @@ private function createAutowiredDefinition($type)
406405
$this->container->setDefinition($argumentId, $argumentDefinition);
407406
} catch (RuntimeException $e) {
408407
$this->autowired[$type] = false;
409-
$this->container->log($this, $e->getMessage());
408+
$this->lastFailure = $e->getMessage();
409+
$this->container->log($this, $this->lastFailure);
410410

411411
return;
412412
} finally {
@@ -427,7 +427,14 @@ private function createTypeNotFoundMessage($type, $label)
427427
$message = sprintf('references %s "%s" but %s.%s', $r->isInterface() ? 'interface' : 'class', $type, $message, $this->createTypeAlternatives($type));
428428
}
429429

430-
return sprintf('Cannot autowire service "%s": %s %s', $this->currentId, $label, $message);
430+
$message = sprintf('Cannot autowire service "%s": %s %s', $this->currentId, $label, $message);
431+
432+
if (null !== $this->lastFailure) {
433+
$message = $this->lastFailure."\n".$message;
434+
$this->lastFailure = null;
435+
}
436+
437+
return $message;
431438
}
432439

433440
private function createTypeAlternatives($type)

0 commit comments

Comments
 (0)
0