Skip to content

Commit 8ab27f6

Browse files
author
Ben Glassman
committed
Add ChainNoResultException for aggregating ChainProvider exceptions.
Create ChainNoResultException class Update ChainProvider::getGecodedData/getReversedData methods to aggregate/throw new exception. Add tests.
1 parent 0e94e32 commit 8ab27f6

File tree

3 files changed

+120
-3
lines changed

3 files changed

+120
-3
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the Geocoder package.
5+
* For the full copyright and license information, please view the LICENSE
6+
* file that was distributed with this source code.
7+
*
8+
* @license MIT License
9+
*/
10+
11+
namespace Geocoder\Exception;
12+
13+
/**
14+
* @author Ben Glassman <[email protected]>
15+
*/
16+
class ChainNoResultException extends NoResultException
17+
{
18+
19+
/**
20+
* Constructor
21+
*
22+
* @param string $message
23+
* @param array $exceptions Array of Exception instances
24+
* @access public
25+
* @return void
26+
*/
27+
public function __construct($message = "", array $exceptions = array())
28+
{
29+
parent::__construct($message);
30+
$this->setExceptions($exceptions);
31+
}
32+
33+
/**
34+
* exceptions
35+
*
36+
* @var array
37+
* @access private
38+
*/
39+
private $exceptions = array();
40+
41+
/**
42+
* Get the exceptions
43+
*
44+
* @access public
45+
* @return void
46+
*/
47+
public function getExceptions()
48+
{
49+
return $this->exceptions;
50+
}
51+
52+
/**
53+
* Set the exceptions
54+
*
55+
* @param array $exceptions Array of Exception instances
56+
* @access public
57+
* @return void
58+
*/
59+
public function setExceptions(array $exceptions)
60+
{
61+
foreach ($exceptions as $exception) {
62+
$this->addException($exception);
63+
}
64+
}
65+
66+
/**
67+
* Add an exception
68+
*
69+
* @param Exception $exception
70+
* @access public
71+
* @return void
72+
*/
73+
public function addException(\Exception $exception)
74+
{
75+
$this->exceptions[] = $exception;
76+
}
77+
78+
}

src/Geocoder/Provider/ChainProvider.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
namespace Geocoder\Provider;
1212

13-
use Geocoder\Exception\NoResultException;
1413
use Geocoder\Exception\InvalidCredentialsException;
14+
use Geocoder\Exception\ChainNoResultException;
1515

1616
/**
1717
* @author Markus Bachmann <[email protected]>
@@ -48,33 +48,39 @@ public function addProvider(ProviderInterface $provider)
4848
*/
4949
public function getGeocodedData($address)
5050
{
51+
$exceptions = array();
52+
5153
foreach ($this->providers as $provider) {
5254
try {
5355
return $provider->getGeocodedData($address);
5456
} catch (InvalidCredentialsException $e) {
5557
throw $e;
5658
} catch (\Exception $e) {
59+
$exceptions[] = $e;
5760
}
5861
}
5962

60-
throw new NoResultException(sprintf('No provider could provide the address "%s"', $address));
63+
throw new ChainNoResultException(sprintf('No provider could provide the address "%s"', $address), $exceptions);
6164
}
6265

6366
/**
6467
* {@inheritDoc}
6568
*/
6669
public function getReversedData(array $coordinates)
6770
{
71+
$exceptions = array();
72+
6873
foreach ($this->providers as $provider) {
6974
try {
7075
return $provider->getReversedData($coordinates);
7176
} catch (InvalidCredentialsException $e) {
7277
throw $e;
7378
} catch (\Exception $e) {
79+
$exceptions[] = $e;
7480
}
7581
}
7682

77-
throw new NoResultException(sprintf('No provider could provide the coordinated %s', json_encode($coordinates)));
83+
throw new ChainNoResultException(sprintf('No provider could provide the coordinated %s', json_encode($coordinates)), $exceptions);
7884
}
7985

8086
/**

tests/Geocoder/Tests/Provider/ChainProviderTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Geocoder\Tests\TestCase;
66
use Geocoder\Provider\ChainProvider;
7+
use Geocoder\Exception\ChainNoResultException;
78

89
/**
910
* @author Markus Bachmann <[email protected]>
@@ -42,6 +43,22 @@ public function testGetReversedData()
4243
$this->assertEquals(array('foo' => 'bar'), $chain->getReversedData(array('11', '22')));
4344
}
4445

46+
public function testChainProviderReverseThrowsChainNoResultException()
47+
{
48+
$mockOne = $this->getMock('Geocoder\\Provider\\ProviderInterface');
49+
$mockOne->expects($this->exactly(2))
50+
->method('getReversedData')
51+
->will($this->returnCallback(function() { throw new \Exception; }));
52+
53+
$chain = new ChainProvider(array($mockOne, $mockOne));
54+
55+
try {
56+
$chain->getReversedData(array('11', '22'));
57+
} catch (ChainNoResultException $e) {
58+
$this->assertCount(2, $e->getExceptions());
59+
}
60+
}
61+
4562
public function testGetGeocodedData()
4663
{
4764
$mockOne = $this->getMock('Geocoder\\Provider\\ProviderInterface');
@@ -59,4 +76,20 @@ public function testGetGeocodedData()
5976

6077
$this->assertEquals(array('foo' => 'bar'), $chain->getGeocodedData('Paris'));
6178
}
79+
80+
public function testChainProviderGeocodeThrowsChainNoResultException()
81+
{
82+
$mockOne = $this->getMock('Geocoder\\Provider\\ProviderInterface');
83+
$mockOne->expects($this->exactly(2))
84+
->method('getGeocodedData')
85+
->will($this->returnCallback(function() { throw new \Exception; }));
86+
87+
$chain = new ChainProvider(array($mockOne, $mockOne));
88+
89+
try {
90+
$chain->getGeocodedData('Paris');
91+
} catch (ChainNoResultException $e) {
92+
$this->assertCount(2, $e->getExceptions());
93+
}
94+
}
6295
}

0 commit comments

Comments
 (0)