1
0
mirror of https://github.com/guzzle/guzzle.git synced 2025-02-24 01:53:58 +01:00

Fixing error and end events for network errors.

When a networking error occurs, the future response that is created
for the transaction does not receive an exception until after the
future is waited on. When calling getResponse() in an event that
is emitted after a networking error, the response returned will
be a future with no actual data to use and throws when accessed.
This commit updated these events to return null if the response
of the transaction is a future. In these cases, it means that the
response did not complete successfully. I've also added a new method
to make this more explicit: hasResponse().

Closes #867.
This commit is contained in:
Michael Dowling 2014-10-16 10:42:50 -07:00
parent dbf5c0ca51
commit 9fc544db12
3 changed files with 65 additions and 2 deletions

View File

@ -2,6 +2,7 @@
namespace GuzzleHttp\Event;
use GuzzleHttp\Message\ResponseInterface;
use GuzzleHttp\Ring\Future\FutureInterface;
/**
* Event that contains transfer statistics, and can be intercepted.
@ -27,13 +28,23 @@ abstract class AbstractTransferEvent extends AbstractRequestEvent
}
/**
* Get the response
* Returns true/false if a response is available.
*
* @return bool
*/
public function hasResponse()
{
return !($this->transaction->response instanceof FutureInterface);
}
/**
* Get the response.
*
* @return ResponseInterface|null
*/
public function getResponse()
{
return $this->transaction->response;
return $this->hasResponse() ? $this->transaction->response : null;
}
/**

View File

@ -30,6 +30,7 @@ class AbstractTransferEventTest extends \PHPUnit_Framework_TestCase
$e = $this->getMockBuilder('GuzzleHttp\Event\AbstractTransferEvent')
->setConstructorArgs([$t])
->getMockForAbstractClass();
$this->assertTrue($e->hasResponse());
$this->assertSame($t->response, $e->getResponse());
}

51
tests/IntegrationTest.php Normal file
View File

@ -0,0 +1,51 @@
<?php
namespace GuzzleHttp\Tests;
use GuzzleHttp\Client;
use GuzzleHttp\Event\AbstractTransferEvent;
use GuzzleHttp\Pool;
class IntegrationTest extends \PHPUnit_Framework_TestCase
{
/**
* @issue https://github.com/guzzle/guzzle/issues/867
*/
public function testDoesNotFailInEventSystemForNetworkError()
{
$c = new Client();
$r = $c->createRequest(
'GET',
Server::$url,
[
'timeout' => 1,
'connect_timeout' => 1,
'proxy' => 'http://127.0.0.1:123/foo'
]
);
$events = [];
$fn = function(AbstractTransferEvent $event) use (&$events) {
$events[] = [
get_class($event),
$event->hasResponse(),
$event->getResponse()
];
};
$pool = new Pool($c, [$r], [
'error' => $fn,
'end' => $fn
]);
$pool->wait();
$this->assertCount(2, $events);
$this->assertEquals('GuzzleHttp\Event\ErrorEvent', $events[0][0]);
$this->assertFalse($events[0][1]);
$this->assertNull($events[0][2]);
$this->assertEquals('GuzzleHttp\Event\EndEvent', $events[1][0]);
$this->assertFalse($events[1][1]);
$this->assertNull($events[1][2]);
}
}