8000 [DependencyInjection] Improve ParameterNotFoundException when accessi… · symfony/symfony@df70f06 · GitHub
[go: up one dir, main page]

Skip to content

Commit df70f06

Browse files
wouterjfabpot
authored andcommitted
[DependencyInjection] Improve ParameterNotFoundException when accessing a nested parameter
1 parent ccb684a commit df70f06

File tree

3 files changed

+45
-29
lines changed

3 files changed

+45
-29
lines changed

src/Symfony/Component/DependencyInjection/Exception/ParameterNotFoundException.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,23 @@ class ParameterNotFoundException extends InvalidArgumentException
2222
private $sourceId;
2323
private $sourceKey;
2424
private $alternatives;
25+
private $nonNestedAlternative;
2526

2627
/**
27-
* @param string $key The requested parameter key
28-
* @param string $sourceId The service id that references the non-existent parameter
29-
* @param string $sourceKey The parameter key that references the non-existent parameter
30-
* @param \Exception $previous The previous exception
31-
* @param string[] $alternatives Some parameter name alternatives
28+
* @param string $key The requested parameter key
29+
* @param string $sourceId The service id that references the non-existent parameter
30+
* @param string $sourceKey The parameter key that references the non-existent parameter
31+
* @param \Exception $previous The previous exception
32+
* @param string[] $alternatives Some parameter name alternatives
33+
* @param string|null $nonNestedAlternative The alternative parameter name when the user expected dot notation for nested parameters
3234
*/
33-
public function __construct($key, $sourceId = null, $sourceKey = null, \Exception $previous = null, array $alternatives = array())
35+
public function __construct($key, $sourceId = null, $sourceKey = null, \Exception $previous = null, array $alternatives = array(), $nonNestedAlternative = null)
3436
{
3537
$this->key = $key;
3638
$this->sourceId = $sourceId;
3739
$this->sourceKey = $sourceKey;
3840
$this->alternatives = $alternatives;
41+
$this->nonNestedAlternative = $nonNestedAlternative;
3942

4043
parent::__construct('', 0, $previous);
4144

@@ -59,6 +62,8 @@ public function updateRepr()
5962
$this->message .= ' Did you mean one of these: "';
6063
}
6164
$this->message .= implode('", "', $this->alternatives).'"?';
65+
} elseif (null !== $this->nonNestedAlternative) {
66+
$this->message .= ' You cannot access nested array items, do you want to inject "'.$this->nonNestedAlternative.'" instead?';
6267
}
6368
}
6469

src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,23 @@ public function get($name)
8181
}
8282
}
8383

84-
throw new ParameterNotFoundException($name, null, null, null, $alternatives);
84+
$nonNestedAlternative = null;
85+
if (!count($alternatives) && false !== strpos($name, '.')) {
86+
$namePartsLength = array_map('strlen', explode('.', $name));
87+
$key = substr($name, 0, -1 * (1 + array_pop($namePartsLength)));
88+
while (count($namePartsLength)) {
89+
if ($this->has($key)) {
90+
if (is_array($this->get($key))) {
91+
$nonNestedAlternative = $key;
92+
}
93+
break;
94+
}
95+
96+
$key = substr($key, 0, -1 * (1 + array_pop($namePartsLength)));
97+
}
98+
}
99+
100+
throw new ParameterNotFoundException($name, null, null, null, $alternatives, $nonNestedAlternative);
85101
}
86102

87103
return $this->parameters[$name];

src/Symfony/Component/DependencyInjection/Tests/ParameterBag/ParameterBagTest.php

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -71,37 +71,32 @@ public function testGetSet()
7171
}
7272
}
7373

74-
public function testGetThrowParameterNotFoundException()
74+
/**
75+
* @dataProvider provideGetThrowParameterNotFoundExceptionData
76+
*/
77+
public function testGetThrowParameterNotFoundException($parameterKey, $exceptionMessage)
7578
{
7679
$bag = new ParameterBag(array(
7780
'foo' => 'foo',
7881
'bar' => 'bar',
7982
'baz' => 'baz',
83+
'fiz' => array('bar' => array('boo' => 12)),
8084
));
8185

82-
try {
83-
$bag->get('foo1');
84-
$this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
85-
} catch (\Exception $e) {
86-
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
87-
$this->assertEquals('You have requested a non-existent parameter "foo1". Did you mean this: "foo"?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException with some advices');
88-
}
86+
$this->setExpectedException('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $exceptionMessage);
8987

90-
try {
91-
$bag->get('bag');
92-
$this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
93-
} catch (\Exception $e) {
94-
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
95-
$this->assertEquals('You have requested a non-existent parameter "bag". Did you mean one of these: "bar", "baz"?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException with some advices');
96-
}
88+
$bag->get($parameterKey);
89+
}
9790

98-
try {
99-
$bag->get('');
100-
$this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
101-
} catch (\Exception $e) {
102-
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
103-
$this->assertEquals('You have requested a non-existent parameter "".', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException with some advices');
104-
}
91+
public function provideGetThrowParameterNotFoundExceptionData()
92+
{
93+
return array(
94+
array('foo1', 'You have requested a non-existent parameter "foo1". Did you mean this: "foo"?'),
95+
array('bag', 'You have requested a non-existent parameter "bag". Did you mean one of these: "bar", "baz"?'),
96+
array('', 'You have requested a non-existent parameter "".'),
97+
98+
array('fiz.bar.boo', 'You have requested a non-existent parameter "fiz.bar.boo". You cannot access nested array items, do you want to inject "fiz" instead?'),
99+
);
105100
}
106101

107102
public function testHas()

0 commit comments

Comments
 (0)
0