[DependencyInjection] added NonExistentParameterException that indicates where a non-existent parameter is being used

This commit is contained in:
Fabien Potencier 2011-04-26 12:31:40 +02:00
parent e68f8f40b9
commit 175f944f93
6 changed files with 147 additions and 23 deletions

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\NonExistentParameterException;
/**
* Resolves all parameter placeholders "%somevalue%" to their real values.
@ -31,18 +32,24 @@ class ResolveParameterPlaceHoldersPass implements CompilerPassInterface
{
$this->parameterBag = $container->getParameterBag();
foreach ($container->getDefinitions() as $definition) {
$definition->setClass($this->resolveValue($definition->getClass()));
$definition->setFile($this->resolveValue($definition->getFile()));
$definition->setArguments($this->resolveValue($definition->getArguments()));
foreach ($container->getDefinitions() as $id => $definition) {
try {
$definition->setClass($this->resolveValue($definition->getClass()));
$definition->setFile($this->resolveValue($definition->getFile()));
$definition->setArguments($this->resolveValue($definition->getArguments()));
$calls = array();
foreach ($definition->getMethodCalls() as $name => $arguments) {
$calls[$this->resolveValue($name)] = $this->resolveValue($arguments);
$calls = array();
foreach ($definition->getMethodCalls() as $name => $arguments) {
$calls[$this->resolveValue($name)] = $this->resolveValue($arguments);
}
$definition->setMethodCalls($calls);
$definition->setProperties($this->resolveValue($definition->getProperties()));
} catch (NonExistentParameterException $e) {
$e->setSourceId($id);
throw $e;
}
$definition->setMethodCalls($calls);
$definition->setProperties($this->resolveValue($definition->getProperties()));
}
$aliases = array();
@ -53,7 +60,13 @@ class ResolveParameterPlaceHoldersPass implements CompilerPassInterface
$parameterBag = $container->getParameterBag();
foreach ($parameterBag->all() as $key => $value) {
$parameterBag->set($key, $this->resolveValue($value));
try {
$parameterBag->set($key, $this->resolveValue($value));
} catch (NonExistentParameterException $e) {
$e->setSourceKey($key);
throw $e;
}
}
}

View File

@ -0,0 +1,80 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection\Exception;
/**
* This exception is thrown when a non-existent parameter is used.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class NonExistentParameterException extends InvalidArgumentException
{
private $key;
private $sourceId;
private $sourceKey;
/**
* Constructor.
*
* @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
*/
public function __construct($key, $sourceId = null, $sourceKey = null)
{
$this->key = $key;
$this->sourceId = $sourceId;
$this->sourceKey = $sourceKey;
$this->updateRepr();
}
public function updateRepr()
{
if (null !== $this->sourceId) {
$this->message = sprintf('The service "%s" has a dependency on a non-existent parameter "%s".', $this->sourceId, $this->key);
} elseif (null !== $this->sourceKey) {
$this->message = sprintf('The parameter "%s" has a dependency on a non-existent parameter "%s".', $this->sourceKey, $this->key);
} else {
$this->message = sprintf('You have requested a non-existent parameter "%s".', $this->key);
}
}
public function getKey()
{
return $this->key;
}
public function getSourceId()
{
return $this->sourceId;
}
public function getSourceKey()
{
return $this->sourceKey;
}
public function setSourceId($sourceId)
{
$this->sourceId = $sourceId;
$this->updateRepr();
}
public function setSourceKey($sourceKey)
{
$this->sourceKey = $sourceKey;
$this->updateRepr();
}
}

View File

@ -11,6 +11,8 @@
namespace Symfony\Component\DependencyInjection\ParameterBag;
use Symfony\Component\DependencyInjection\Exception\NonExistentParameterException;
/**
*
* @author Fabien Potencier <fabien@symfony.com>
@ -74,7 +76,7 @@ class ParameterBag implements ParameterBagInterface
$name = strtolower($name);
if (!array_key_exists($name, $this->parameters)) {
throw new \InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
throw new NonExistentParameterException($name);
}
return $this->parameters[$name];
@ -109,7 +111,13 @@ class ParameterBag implements ParameterBagInterface
public function resolve()
{
foreach ($this->parameters as $key => $value) {
$this->parameters[$key] = $this->resolveValue($value);
try {
$this->parameters[$key] = $this->resolveValue($value);
} catch (NonExistentParameterException $e) {
$e->setSourceKey($key);
throw $e;
}
}
}

View File

@ -11,6 +11,8 @@
namespace Symfony\Component\DependencyInjection\ParameterBag;
use Symfony\Component\DependencyInjection\Exception\NonExistentParameterException;
/**
* ParameterBagInterface.
*
@ -44,7 +46,7 @@ interface ParameterBagInterface
*
* @return mixed The parameter value
*
* @throws \InvalidArgumentException if the parameter is not defined
* @throws NonExistentParameterException if the parameter is not defined
*/
function get($name);

View File

@ -83,7 +83,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
$this->fail('->getParameter() thrown an \InvalidArgumentException if the key does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('\InvalidArgumentException', $e, '->getParameter() thrown an \InvalidArgumentException if the key does not exist');
$this->assertEquals('The parameter "baba" must be defined.', $e->getMessage(), '->getParameter() thrown an \InvalidArgumentException if the key does not exist');
$this->assertEquals('You have requested a non-existent parameter "baba".', $e->getMessage(), '->getParameter() thrown an \InvalidArgumentException if the key does not exist');
}
}

View File

@ -12,6 +12,7 @@
namespace Symfony\Tests\Component\DependencyInjection\ParameterBag;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Exception\NonExistentParameterException;
class ParameterBagTest extends \PHPUnit_Framework_TestCase
{
@ -62,7 +63,7 @@ class ParameterBagTest extends \PHPUnit_Framework_TestCase
$this->fail('->get() throws an \InvalidArgumentException if the key does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('\InvalidArgumentException', $e, '->get() throws an \InvalidArgumentException if the key does not exist');
$this->assertEquals('The parameter "baba" must be defined.', $e->getMessage(), '->get() throws an \InvalidArgumentException if the key does not exist');
$this->assertEquals('You have requested a non-existent parameter "baba".', $e->getMessage(), '->get() throws an \InvalidArgumentException if the key does not exist');
}
}
@ -99,17 +100,37 @@ class ParameterBagTest extends \PHPUnit_Framework_TestCase
try {
$bag->resolveValue('%foobar%', array());
$this->fail('->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existent parameter');
} catch (\Exception $e) {
$this->assertInstanceOf('\InvalidArgumentException', $e, '->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existent parameter');
$this->assertEquals('The parameter "foobar" must be defined.', $e->getMessage(), '->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existent parameter');
} catch (NonExistentParameterException $e) {
$this->assertEquals('You have requested a non-existent parameter "foobar".', $e->getMessage(), '->resolveValue() throws a NonExistentParameterException if a placeholder references a non-existent parameter');
}
try {
$bag->resolveValue('foo %foobar% bar', array());
$this->fail('->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existent parameter');
} catch (\Exception $e) {
$this->assertInstanceOf('\InvalidArgumentException', $e, '->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existent parameter');
$this->assertEquals('The parameter "foobar" must be defined.', $e->getMessage(), '->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existent parameter');
$this->fail('->resolveValue() throws a NonExistentParameterException if a placeholder references a non-existent parameter');
} catch (NonExistentParameterException $e) {
$this->assertEquals('You have requested a non-existent parameter "foobar".', $e->getMessage(), '->resolveValue() throws a NonExistentParameterException if a placeholder references a non-existent parameter');
}
}
/**
* @covers Symfony\Component\DependencyInjection\ParameterBag\ParameterBag::resolve
*/
public function testResolveIndicatesWhyAParameterIsNeeded()
{
$bag = new ParameterBag(array('foo' => '%bar%'));
try {
$bag->resolve();
} catch (NonExistentParameterException $e) {
$this->assertEquals('The parameter "foo" has a dependency on a non-existent parameter "bar".', $e->getMessage());
}
$bag = new ParameterBag(array('foo' => '%bar%'));
try {
$bag->resolve();
} catch (NonExistentParameterException $e) {
$this->assertEquals('The parameter "foo" has a dependency on a non-existent parameter "bar".', $e->getMessage());
}
}
}