Skip to content

Commit d82bdb7

Browse files
committed
Merge pull request #264 from benglass/master
Add ChainNoResultException for aggregating ChainProvider exceptions.
2 parents 0e94e32 + 7e90be6 commit d82bdb7

File tree

3 files changed

+88
-3
lines changed

3 files changed

+88
-3
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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+
* Exceptions from chained providers
21+
*
22+
* @var array
23+
*/
24+
private $exceptions = array();
25+
26+
/**
27+
* Constructor
28+
*
29+
* @param string $message
30+
* @param array $exceptions Array of Exception instances
31+
*/
32+
public function __construct($message = "", array $exceptions = array())
33+
{
34+
parent::__construct($message);
35+
$this->exceptions = $exceptions;
36+
}
37+
38+
/**
39+
* Get the exceptions from chained providers
40+
*/
41+
public function getExceptions()
42+
{
43+
return $this->exceptions;
44+
}
45+
46+
}

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)