From 8ab27f6107644a3bc14e2a8f5498a7215b0000d7 Mon Sep 17 00:00:00 2001 From: Ben Glassman Date: Thu, 12 Sep 2013 20:22:43 -0400 Subject: [PATCH 1/2] Add ChainNoResultException for aggregating ChainProvider exceptions. Create ChainNoResultException class Update ChainProvider::getGecodedData/getReversedData methods to aggregate/throw new exception. Add tests. --- .../Exception/ChainNoResultException.php | 78 +++++++++++++++++++ src/Geocoder/Provider/ChainProvider.php | 12 ++- .../Tests/Provider/ChainProviderTest.php | 33 ++++++++ 3 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 src/Geocoder/Exception/ChainNoResultException.php diff --git a/src/Geocoder/Exception/ChainNoResultException.php b/src/Geocoder/Exception/ChainNoResultException.php new file mode 100644 index 000000000..edf18af42 --- /dev/null +++ b/src/Geocoder/Exception/ChainNoResultException.php @@ -0,0 +1,78 @@ + + */ +class ChainNoResultException extends NoResultException +{ + + /** + * Constructor + * + * @param string $message + * @param array $exceptions Array of Exception instances + * @access public + * @return void + */ + public function __construct($message = "", array $exceptions = array()) + { + parent::__construct($message); + $this->setExceptions($exceptions); + } + + /** + * exceptions + * + * @var array + * @access private + */ + private $exceptions = array(); + + /** + * Get the exceptions + * + * @access public + * @return void + */ + public function getExceptions() + { + return $this->exceptions; + } + + /** + * Set the exceptions + * + * @param array $exceptions Array of Exception instances + * @access public + * @return void + */ + public function setExceptions(array $exceptions) + { + foreach ($exceptions as $exception) { + $this->addException($exception); + } + } + + /** + * Add an exception + * + * @param Exception $exception + * @access public + * @return void + */ + public function addException(\Exception $exception) + { + $this->exceptions[] = $exception; + } + +} diff --git a/src/Geocoder/Provider/ChainProvider.php b/src/Geocoder/Provider/ChainProvider.php index 616d6a84b..ced54c3df 100644 --- a/src/Geocoder/Provider/ChainProvider.php +++ b/src/Geocoder/Provider/ChainProvider.php @@ -10,8 +10,8 @@ namespace Geocoder\Provider; -use Geocoder\Exception\NoResultException; use Geocoder\Exception\InvalidCredentialsException; +use Geocoder\Exception\ChainNoResultException; /** * @author Markus Bachmann @@ -48,16 +48,19 @@ 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); } /** @@ -65,16 +68,19 @@ public function getGeocodedData($address) */ 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); } /** diff --git a/tests/Geocoder/Tests/Provider/ChainProviderTest.php b/tests/Geocoder/Tests/Provider/ChainProviderTest.php index 24152a91b..e67ca49d4 100644 --- a/tests/Geocoder/Tests/Provider/ChainProviderTest.php +++ b/tests/Geocoder/Tests/Provider/ChainProviderTest.php @@ -4,6 +4,7 @@ use Geocoder\Tests\TestCase; use Geocoder\Provider\ChainProvider; +use Geocoder\Exception\ChainNoResultException; /** * @author Markus Bachmann @@ -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'); @@ -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()); + } + } } From 7e90be6807d098f7a3d06b0401eebf419d1b4a02 Mon Sep 17 00:00:00 2001 From: Ben Glassman Date: Sun, 15 Sep 2013 20:47:30 -0400 Subject: [PATCH 2/2] Remove add/setException methods. Remove @access/@return annotations. Move $exceptions property above methods. --- .../Exception/ChainNoResultException.php | 50 ++++--------------- 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/src/Geocoder/Exception/ChainNoResultException.php b/src/Geocoder/Exception/ChainNoResultException.php index edf18af42..c4475d227 100644 --- a/src/Geocoder/Exception/ChainNoResultException.php +++ b/src/Geocoder/Exception/ChainNoResultException.php @@ -17,62 +17,30 @@ class ChainNoResultException extends NoResultException { /** - * Constructor - * - * @param string $message - * @param array $exceptions Array of Exception instances - * @access public - * @return void - */ - public function __construct($message = "", array $exceptions = array()) - { - parent::__construct($message); - $this->setExceptions($exceptions); - } - - /** - * exceptions + * Exceptions from chained providers * * @var array - * @access private */ private $exceptions = array(); /** - * Get the exceptions - * - * @access public - * @return void - */ - public function getExceptions() - { - return $this->exceptions; - } - - /** - * Set the exceptions + * Constructor * + * @param string $message * @param array $exceptions Array of Exception instances - * @access public - * @return void */ - public function setExceptions(array $exceptions) + public function __construct($message = "", array $exceptions = array()) { - foreach ($exceptions as $exception) { - $this->addException($exception); - } + parent::__construct($message); + $this->exceptions = $exceptions; } /** - * Add an exception - * - * @param Exception $exception - * @access public - * @return void + * Get the exceptions from chained providers */ - public function addException(\Exception $exception) + public function getExceptions() { - $this->exceptions[] = $exception; + return $this->exceptions; } }