Skip to content

Commit

Permalink
Merge pull request #264 from benglass/master
Browse files Browse the repository at this point in the history
Add ChainNoResultException for aggregating ChainProvider exceptions.
  • Loading branch information
willdurand committed Sep 16, 2013
2 parents 0e94e32 + 7e90be6 commit d82bdb7
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 3 deletions.
46 changes: 46 additions & 0 deletions src/Geocoder/Exception/ChainNoResultException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

/**
* This file is part of the Geocoder package.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @license MIT License
*/

namespace Geocoder\Exception;

/**
* @author Ben Glassman <bglassman@gmail.com>
*/
class ChainNoResultException extends NoResultException
{

/**
* Exceptions from chained providers
*
* @var array
*/
private $exceptions = array();

/**
* Constructor
*
* @param string $message
* @param array $exceptions Array of Exception instances
*/
public function __construct($message = "", array $exceptions = array())
{
parent::__construct($message);
$this->exceptions = $exceptions;
}

/**
* Get the exceptions from chained providers
*/
public function getExceptions()
{
return $this->exceptions;
}

}
12 changes: 9 additions & 3 deletions src/Geocoder/Provider/ChainProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

namespace Geocoder\Provider;

use Geocoder\Exception\NoResultException;
use Geocoder\Exception\InvalidCredentialsException;
use Geocoder\Exception\ChainNoResultException;

/**
* @author Markus Bachmann <markus.bachmann@bachi.biz>
Expand Down Expand Up @@ -48,33 +48,39 @@ public function addProvider(ProviderInterface $provider)
*/
public function getGeocodedData($address)
{
$exceptions = array();

foreach ($this->providers as $provider) {
try {
return $provider->getGeocodedData($address);
} catch (InvalidCredentialsException $e) {
throw $e;
} catch (\Exception $e) {
$exceptions[] = $e;
}
}

throw new NoResultException(sprintf('No provider could provide the address "%s"', $address));
throw new ChainNoResultException(sprintf('No provider could provide the address "%s"', $address), $exceptions);
}

/**
* {@inheritDoc}
*/
public function getReversedData(array $coordinates)
{
$exceptions = array();

foreach ($this->providers as $provider) {
try {
return $provider->getReversedData($coordinates);
} catch (InvalidCredentialsException $e) {
throw $e;
} catch (\Exception $e) {
$exceptions[] = $e;
}
}

throw new NoResultException(sprintf('No provider could provide the coordinated %s', json_encode($coordinates)));
throw new ChainNoResultException(sprintf('No provider could provide the coordinated %s', json_encode($coordinates)), $exceptions);
}

/**
Expand Down
33 changes: 33 additions & 0 deletions tests/Geocoder/Tests/Provider/ChainProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Geocoder\Tests\TestCase;
use Geocoder\Provider\ChainProvider;
use Geocoder\Exception\ChainNoResultException;

/**
* @author Markus Bachmann <markus.bachmann@bachi.biz>
Expand Down Expand Up @@ -42,6 +43,22 @@ public function testGetReversedData()
$this->assertEquals(array('foo' => 'bar'), $chain->getReversedData(array('11', '22')));
}

public function testChainProviderReverseThrowsChainNoResultException()
{
$mockOne = $this->getMock('Geocoder\\Provider\\ProviderInterface');
$mockOne->expects($this->exactly(2))
->method('getReversedData')
->will($this->returnCallback(function() { throw new \Exception; }));

$chain = new ChainProvider(array($mockOne, $mockOne));

try {
$chain->getReversedData(array('11', '22'));
} catch (ChainNoResultException $e) {
$this->assertCount(2, $e->getExceptions());
}
}

public function testGetGeocodedData()
{
$mockOne = $this->getMock('Geocoder\\Provider\\ProviderInterface');
Expand All @@ -59,4 +76,20 @@ public function testGetGeocodedData()

$this->assertEquals(array('foo' => 'bar'), $chain->getGeocodedData('Paris'));
}

public function testChainProviderGeocodeThrowsChainNoResultException()
{
$mockOne = $this->getMock('Geocoder\\Provider\\ProviderInterface');
$mockOne->expects($this->exactly(2))
->method('getGeocodedData')
->will($this->returnCallback(function() { throw new \Exception; }));

$chain = new ChainProvider(array($mockOne, $mockOne));

try {
$chain->getGeocodedData('Paris');
} catch (ChainNoResultException $e) {
$this->assertCount(2, $e->getExceptions());
}
}
}

0 comments on commit d82bdb7

Please sign in to comment.