Skip to content

Commit

Permalink
[DependencyInjection] Improve ParameterNotFoundException when accessi…
Browse files Browse the repository at this point in the history
…ng a nested parameter
  • Loading branch information
wouterj authored and fabpot committed Sep 14, 2016
1 parent ccb684a commit df70f06
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 29 deletions.
Expand Up @@ -22,20 +22,23 @@ class ParameterNotFoundException extends InvalidArgumentException
private $sourceId;
private $sourceKey;
private $alternatives;
private $nonNestedAlternative;

/**
* @param string $key The requested parameter key
* @param string $sourceId The service id that references the non-existent parameter
* @param string $sourceKey The parameter key that references the non-existent parameter
* @param \Exception $previous The previous exception
* @param string[] $alternatives Some parameter name alternatives
* @param string $key The requested parameter key
* @param string $sourceId The service id that references the non-existent parameter
* @param string $sourceKey The parameter key that references the non-existent parameter
* @param \Exception $previous The previous exception
* @param string[] $alternatives Some parameter name alternatives
* @param string|null $nonNestedAlternative The alternative parameter name when the user expected dot notation for nested parameters
*/
public function __construct($key, $sourceId = null, $sourceKey = null, \Exception $previous = null, array $alternatives = array())
public function __construct($key, $sourceId = null, $sourceKey = null, \Exception $previous = null, array $alternatives = array(), $nonNestedAlternative = null)
{
$this->key = $key;
$this->sourceId = $sourceId;
$this->sourceKey = $sourceKey;
$this->alternatives = $alternatives;
$this->nonNestedAlternative = $nonNestedAlternative;

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

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

Expand Down
Expand Up @@ -81,7 +81,23 @@ public function get($name)
}
}

throw new ParameterNotFoundException($name, null, null, null, $alternatives);
$nonNestedAlternative = null;
if (!count($alternatives) && false !== strpos($name, '.')) {
$namePartsLength = array_map('strlen', explode('.', $name));
$key = substr($name, 0, -1 * (1 + array_pop($namePartsLength)));
while (count($namePartsLength)) {
if ($this->has($key)) {
if (is_array($this->get($key))) {
$nonNestedAlternative = $key;
}
break;
}

$key = substr($key, 0, -1 * (1 + array_pop($namePartsLength)));
}
}

throw new ParameterNotFoundException($name, null, null, null, $alternatives, $nonNestedAlternative);
}

return $this->parameters[$name];
Expand Down
Expand Up @@ -71,37 +71,32 @@ public function testGetSet()
}
}

public function testGetThrowParameterNotFoundException()
/**
* @dataProvider provideGetThrowParameterNotFoundExceptionData
*/
public function testGetThrowParameterNotFoundException($parameterKey, $exceptionMessage)
{
$bag = new ParameterBag(array(
'foo' => 'foo',
'bar' => 'bar',
'baz' => 'baz',
'fiz' => array('bar' => array('boo' => 12)),
));

try {
$bag->get('foo1');
$this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
$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');
}
$this->setExpectedException('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $exceptionMessage);

try {
$bag->get('bag');
$this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
$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');
}
$bag->get($parameterKey);
}

try {
$bag->get('');
$this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
$this->assertEquals('You have requested a non-existent parameter "".', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException with some advices');
}
public function provideGetThrowParameterNotFoundExceptionData()
{
return array(
array('foo1', 'You have requested a non-existent parameter "foo1". Did you mean this: "foo"?'),
array('bag', 'You have requested a non-existent parameter "bag". Did you mean one of these: "bar", "baz"?'),
array('', 'You have requested a non-existent parameter "".'),

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?'),
);
}

public function testHas()
Expand Down

0 comments on commit df70f06

Please sign in to comment.