Skip to content

Commit

Permalink
[DependencyInjection] Add suggestion on ServiceNotFoundException
Browse files Browse the repository at this point in the history
  • Loading branch information
lyrixx committed Apr 30, 2013
1 parent f44db48 commit 729db0f
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
14 changes: 13 additions & 1 deletion src/Symfony/Component/DependencyInjection/Container.php
Expand Up @@ -285,7 +285,19 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE
}

if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) {
throw new ServiceNotFoundException($id);
if (!$id) {
throw new ServiceNotFoundException($id);
}

$alternatives = array();
foreach (array_keys($this->services) as $key) {
$lev = levenshtein($id, $key);
if ($lev <= strlen($id) / 3 || false !== strpos($key, $id)) {
$alternatives[] = $key;
}
}

throw new ServiceNotFoundException($id, null, null, $alternatives);
}
}

Expand Down
Expand Up @@ -21,14 +21,24 @@ class ServiceNotFoundException extends InvalidArgumentException
private $id;
private $sourceId;

public function __construct($id, $sourceId = null, \Exception $previous = null)
public function __construct($id, $sourceId = null, \Exception $previous = null, array $alternatives = array())
{
if (null === $sourceId) {
$msg = sprintf('You have requested a non-existent service "%s".', $id);
} else {
$msg = sprintf('The service "%s" has a dependency on a non-existent service "%s".', $sourceId, $id);
}

if ($alternatives) {
if (1 == count($alternatives)) {
$msg .= ' Did you mean this: "';
} elseif (1 < count($alternatives)) {
$msg .= ' Did you mean one of these: "';
}
$msg .= implode('", "', $alternatives);
$msg .= '" ?';
}

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

$this->id = $id;
Expand Down
24 changes: 24 additions & 0 deletions src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php
Expand Up @@ -167,6 +167,30 @@ public function testGet()
$this->assertNull($sc->get('', ContainerInterface::NULL_ON_INVALID_REFERENCE));
}

public function testGetThrowServiceNotFoundException()
{
$sc = new ProjectServiceContainer();
$sc->set('foo', $foo = new \stdClass());
$sc->set('bar', $foo = new \stdClass());
$sc->set('baz', $foo = new \stdClass());

try {
$sc->get('foo1');
$this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist');
$this->assertEquals('You have requested a non-existent service "foo1". Did you mean this: "foo" ?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException with some advices');
}

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

public function testGetCircularReference()
{

Expand Down

0 comments on commit 729db0f

Please sign in to comment.