mirror of
https://github.com/guzzle/guzzle.git
synced 2025-02-24 10:03:27 +01:00
Ensuring exceptions are not thrown in pool
This commit is contained in:
parent
294f670ad3
commit
87470bf043
@ -19,7 +19,7 @@ class CancelledFutureResponse extends FutureResponse
|
||||
*/
|
||||
public static function fromException(RequestException $e)
|
||||
{
|
||||
return new CancelledFutureResponse(new RejectedPromise($e));
|
||||
return new self(new RejectedPromise($e));
|
||||
}
|
||||
|
||||
public function realized()
|
||||
|
16
src/Pool.php
16
src/Pool.php
@ -3,6 +3,7 @@ namespace GuzzleHttp;
|
||||
|
||||
use GuzzleHttp\Event\RequestEvents;
|
||||
use GuzzleHttp\Message\RequestInterface;
|
||||
use GuzzleHttp\Message\ResponseInterface;
|
||||
use GuzzleHttp\Ring\Core;
|
||||
use GuzzleHttp\Ring\Future\FutureInterface;
|
||||
use GuzzleHttp\Event\ListenerAttacherTrait;
|
||||
@ -157,7 +158,9 @@ class Pool implements FutureInterface
|
||||
|
||||
// Dereference any outstanding FutureResponse objects.
|
||||
while ($response = array_pop($this->derefQueue)) {
|
||||
$response->deref();
|
||||
try {
|
||||
$response->deref();
|
||||
} catch (\Exception $e) {}
|
||||
}
|
||||
|
||||
// Clean up no longer needed state.
|
||||
@ -205,7 +208,7 @@ class Pool implements FutureInterface
|
||||
callable $onRejected = null,
|
||||
callable $onProgress = null
|
||||
) {
|
||||
return $this->promise->then($onRejected, $onRejected, $onProgress);
|
||||
return $this->promise->then($onFulfilled, $onRejected, $onProgress);
|
||||
}
|
||||
|
||||
private function coerceIterable($requests)
|
||||
@ -248,12 +251,13 @@ class Pool implements FutureInterface
|
||||
$hash = spl_object_hash($request);
|
||||
$this->derefQueue[$hash] = $response;
|
||||
|
||||
// Use this function for both resolution and rejection.
|
||||
$fn = function ($value) use ($request, $hash) {
|
||||
unset($this->derefQueue[$hash]);
|
||||
$this->deferred->progress([
|
||||
'request' => $request,
|
||||
'result' => $value
|
||||
]);
|
||||
$result = $value instanceof ResponseInterface
|
||||
? ['request' => $request, 'response' => $value, 'error' => null]
|
||||
: ['request' => $request, 'response' => null, 'error' => $value];
|
||||
$this->deferred->progress($result);
|
||||
$this->addNextRequest();
|
||||
};
|
||||
|
||||
|
@ -6,6 +6,7 @@ use GuzzleHttp\Event\ErrorEvent;
|
||||
use GuzzleHttp\Event\CompleteEvent;
|
||||
use GuzzleHttp\Event\EndEvent;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use GuzzleHttp\Ring\Exception\CancelledException;
|
||||
use GuzzleHttp\Ring\Future\FutureInterface;
|
||||
|
||||
/**
|
||||
|
@ -3,7 +3,7 @@ namespace GuzzleHttp\Tests;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Event\RequestEvents;
|
||||
use GuzzleHttp\Exception\CancelledRequestException;
|
||||
use GuzzleHttp\Message\CancelledFutureResponse;
|
||||
use GuzzleHttp\Pool;
|
||||
use GuzzleHttp\Ring\Client\MockAdapter;
|
||||
use GuzzleHttp\Ring\Future\FutureArray;
|
||||
@ -173,18 +173,65 @@ class PoolTest extends \PHPUnit_Framework_TestCase
|
||||
Pool::batch($client, $requests, ['complete' => 'foo']);
|
||||
}
|
||||
|
||||
/**
|
||||
* This does not throw a cancelled access exception because of the
|
||||
* cancelled() check in Pool::addNextRequest.
|
||||
*/
|
||||
public function testDoesNotAddCancelledResponsesToDerefQueue()
|
||||
public function testEmitsProgress()
|
||||
{
|
||||
$c = $this->getClient();
|
||||
$req = $c->createRequest('GET', 'http://foo.com');
|
||||
$req->getEmitter()->on('before', function (BeforeEvent $e) {
|
||||
CancelledRequestException::create($e->getRequest());
|
||||
});
|
||||
$p = new Pool($c, [$req]);
|
||||
$p->deref();
|
||||
$client = new Client(['adapter' => function () {
|
||||
throw new \RuntimeException('No network access');
|
||||
}]);
|
||||
|
||||
$responses = [new Response(200), new Response(404)];
|
||||
$client->getEmitter()->attach(new Mock($responses));
|
||||
$requests = [
|
||||
$client->createRequest('GET', 'http://foo.com/baz'),
|
||||
$client->createRequest('HEAD', 'http://httpbin.org/get')
|
||||
];
|
||||
|
||||
$pool = new Pool($client, $requests);
|
||||
$count = 0;
|
||||
$thenned = null;
|
||||
$pool->then(
|
||||
function ($value) use (&$thenned) {
|
||||
$thenned = $value;
|
||||
},
|
||||
null,
|
||||
function ($result) use (&$count, $requests) {
|
||||
$this->assertSame($requests[$count], $result['request']);
|
||||
if ($count == 0) {
|
||||
$this->assertNull($result['error']);
|
||||
$this->assertEquals(200, $result['response']->getStatusCode());
|
||||
} else {
|
||||
$this->assertInstanceOf(
|
||||
'GuzzleHttp\Exception\ClientException',
|
||||
$result['error']
|
||||
);
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
);
|
||||
|
||||
$pool->deref();
|
||||
$this->assertEquals(2, $count);
|
||||
$this->assertEquals(true, $thenned);
|
||||
}
|
||||
|
||||
public function testDoesNotThrowInErrorEvent()
|
||||
{
|
||||
Server::flush();
|
||||
Server::enqueue([new Response(404)]);
|
||||
$client = new Client();
|
||||
$requests = [$client->createRequest('GET', 'http://foo.com/baz')];
|
||||
$c = false;
|
||||
// "Cancel" the error.
|
||||
$requests[0]->getEmitter()->on(
|
||||
'error',
|
||||
function (ErrorEvent $e) use (&$c) {
|
||||
$c = true;
|
||||
$e->intercept(
|
||||
CancelledFutureResponse::fromException($e->getException())
|
||||
);
|
||||
}
|
||||
);
|
||||
$result = Pool::batch($client, $requests);
|
||||
$this->assertTrue($c);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user