From 27e36f91633b3eaca3a5790fad0ed3138ef121f7 Mon Sep 17 00:00:00 2001 From: Joel Wurtz Date: Sat, 31 Oct 2015 15:32:04 +0100 Subject: [PATCH 1/8] Add async capability --- composer.json | 14 ++++- src/Guzzle6HttpAdapter.php | 11 +++- src/Guzzle6Promise.php | 112 +++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 src/Guzzle6Promise.php diff --git a/composer.json b/composer.json index 8761c8d..841c5e0 100644 --- a/composer.json +++ b/composer.json @@ -16,13 +16,23 @@ ], "require": { "php": ">=5.5.0", - "php-http/httplug": "dev-master", + "php-http/httplug": "dev-feature/async as 1.0.1", "guzzlehttp/guzzle": "^6.0" }, "require-dev": { "ext-curl": "*", - "php-http/adapter-integration-tests": "^0.2@dev" + "php-http/adapter-integration-tests": "dev-feature/async-test" }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/joelwurtz/httplug" + }, + { + "type": "vcs", + "url": "https://github.com/joelwurtz/adapter-integration-tests" + } + ], "provide": { "php-http/client-implementation": "1.0" }, diff --git a/src/Guzzle6HttpAdapter.php b/src/Guzzle6HttpAdapter.php index 7786441..d863c51 100644 --- a/src/Guzzle6HttpAdapter.php +++ b/src/Guzzle6HttpAdapter.php @@ -18,13 +18,14 @@ use Http\Client\Exception\NetworkException; use Http\Client\Exception\RequestException; use Http\Client\Exception\TransferException; +use Http\Client\HttpAsyncClient; use Http\Client\HttpClient; use Psr\Http\Message\RequestInterface; /** * @author David de Boer */ -class Guzzle6HttpAdapter implements HttpClient +class Guzzle6HttpAdapter implements HttpClient, HttpAsyncClient { /** * @var ClientInterface @@ -53,6 +54,14 @@ public function sendRequest(RequestInterface $request) } } + /** + * {@inheritdoc} + */ + public function sendAsyncRequest(RequestInterface $request) + { + return new Guzzle6Promise($this->client->sendAsync($request)); + } + /** * Converts a Guzzle exception into an Httplug exception. * diff --git a/src/Guzzle6Promise.php b/src/Guzzle6Promise.php new file mode 100644 index 0000000..76481bf --- /dev/null +++ b/src/Guzzle6Promise.php @@ -0,0 +1,112 @@ +promise = $promise; + $this->state = self::PENDING; + } + + /** + * {@inheritdoc} + */ + public function then(callable $onFulfilled = null, callable $onRejected = null) + { + $onFulfilledInternal = function ($response) use($onFulfilled) { + $this->response = $response; + $this->state = self::FULFILLED; + + return $onFulfilled($this->response); + }; + + $onRejectedInternal = function ($reason) use($onRejected) { + if (!($reason instanceof RequestException)) { + throw new \RuntimeException("Invalid reason"); + } + + $this->state = self::REJECTED; + $this->error = new Exception\NetworkException($reason->getMessage(), $reason->getRequest(), $reason); + + if ($reason->hasResponse()) { + $this->error = new Exception\HttpException($reason->getMessage(), $reason->getRequest(), $reason->getResponse(), $reason); + } + + return $onRejected($this->error); + }; + + $this->promise = $this->promise->then($onFulfilledInternal, $onRejectedInternal); + + return new static($this->promise); + } + + /** + * {@inheritdoc} + */ + public function getState() + { + return $this->state; + } + + + /** + * {@inheritdoc} + */ + public function getResponse() + { + if (self::FULFILLED !== $this->state) { + throw new \LogicException("Response not available for the current state"); + } + + return $this->response; + } + + /** + * {@inheritdoc} + */ + public function getError() + { + if (self::REJECTED !== $this->state) { + throw new \LogicException("Error not available for the current state"); + } + + return $this->error; + } + + /** + * {@inheritdoc} + */ + public function wait() + { + $this->promise->wait(false); + } +} + \ No newline at end of file From b77828b04d5a86e7d77b9d91b245a6e3cc207611 Mon Sep 17 00:00:00 2001 From: Joel Wurtz Date: Sat, 31 Oct 2015 16:20:30 +0100 Subject: [PATCH 2/8] Adapt tests for speratation of async / sync test --- tests/Guzzle6CurlHttpAsyncAdapterTest.php | 30 +++++++++++++++ tests/Guzzle6HttpAdapterTest.php | 3 +- tests/Guzzle6HttpAsyncAdapterTest.php | 37 +++++++++++++++++++ .../Guzzle6MultiCurlHttpAsyncAdapterTest.php | 28 ++++++++++++++ tests/Guzzle6StreamHttpAsyncAdapterTest.php | 28 ++++++++++++++ 5 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 tests/Guzzle6CurlHttpAsyncAdapterTest.php create mode 100644 tests/Guzzle6HttpAsyncAdapterTest.php create mode 100644 tests/Guzzle6MultiCurlHttpAsyncAdapterTest.php create mode 100644 tests/Guzzle6StreamHttpAsyncAdapterTest.php diff --git a/tests/Guzzle6CurlHttpAsyncAdapterTest.php b/tests/Guzzle6CurlHttpAsyncAdapterTest.php new file mode 100644 index 0000000..defb4d5 --- /dev/null +++ b/tests/Guzzle6CurlHttpAsyncAdapterTest.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. + */ + +namespace Http\Adapter\Tests; + +use GuzzleHttp\Handler\CurlHandler; + +/** + * @requires PHP 5.5 + * + * @author GeLo + */ +class Guzzle6CurlHttpAsyncAdapterTest extends Guzzle6HttpAsyncAdapterTest +{ + /** + * {@inheritdoc} + */ + protected function createHandler() + { + return new CurlHandler(); + } +} diff --git a/tests/Guzzle6HttpAdapterTest.php b/tests/Guzzle6HttpAdapterTest.php index 156bc74..6193fee 100644 --- a/tests/Guzzle6HttpAdapterTest.php +++ b/tests/Guzzle6HttpAdapterTest.php @@ -13,11 +13,12 @@ use GuzzleHttp\Client; use Http\Adapter\Guzzle6HttpAdapter; +use Http\Client\Tests\HttpClientTest; /** * @author GeLo */ -abstract class Guzzle6HttpAdapterTest extends HttpAdapterTest +abstract class Guzzle6HttpAdapterTest extends HttpClientTest { /** * {@inheritdoc} diff --git a/tests/Guzzle6HttpAsyncAdapterTest.php b/tests/Guzzle6HttpAsyncAdapterTest.php new file mode 100644 index 0000000..db303fc --- /dev/null +++ b/tests/Guzzle6HttpAsyncAdapterTest.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. + */ + +namespace Http\Adapter\Tests; + +use GuzzleHttp\Client; +use Http\Adapter\Guzzle6HttpAdapter; +use Http\Client\Tests\HttpAsyncClientTest; + +/** + * @author GeLo + */ +abstract class Guzzle6HttpAsyncAdapterTest extends HttpAsyncClientTest +{ + /** + * {@inheritdoc} + */ + protected function createHttpAsyncClient() + { + return new Guzzle6HttpAdapter(new Client(['handler' => $this->createHandler()])); + } + + /** + * Returns a handler for the client + * + * @return object + */ + abstract protected function createHandler(); +} diff --git a/tests/Guzzle6MultiCurlHttpAsyncAdapterTest.php b/tests/Guzzle6MultiCurlHttpAsyncAdapterTest.php new file mode 100644 index 0000000..a3c267a --- /dev/null +++ b/tests/Guzzle6MultiCurlHttpAsyncAdapterTest.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. + */ + +namespace Http\Adapter\Tests; + +use GuzzleHttp\Handler\CurlMultiHandler; + +/** + * @author GeLo + */ +class Guzzle6MultiCurlHttpAsyncAdapterTest extends Guzzle6HttpAsyncAdapterTest +{ + /** + * {@inheritdoc} + */ + protected function createHandler() + { + return new CurlMultiHandler(); + } +} diff --git a/tests/Guzzle6StreamHttpAsyncAdapterTest.php b/tests/Guzzle6StreamHttpAsyncAdapterTest.php new file mode 100644 index 0000000..51dae06 --- /dev/null +++ b/tests/Guzzle6StreamHttpAsyncAdapterTest.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. + */ + +namespace Http\Adapter\Tests; + +use GuzzleHttp\Handler\StreamHandler; + +/** + * @author GeLo + */ +class Guzzle6StreamHttpAsyncAdapterTest extends Guzzle6HttpAsyncAdapterTest +{ + /** + * {@inheritdoc} + */ + protected function createHandler() + { + return new StreamHandler(); + } +} From 3249580d3e50282af6f9240e3f6f5a79a2975d6d Mon Sep 17 00:00:00 2001 From: Joel Wurtz Date: Sat, 31 Oct 2015 18:25:55 +0100 Subject: [PATCH 3/8] Add provided implementation --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 841c5e0..0d756d9 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,8 @@ } ], "provide": { - "php-http/client-implementation": "1.0" + "php-http/client-implementation": "1.0", + "php-http/async-client-implementation": "1.0" }, "autoload": { "psr-4": { From 02c5f75746780f1bcd4f824d3ff415d83ce94cfe Mon Sep 17 00:00:00 2001 From: Joel Wurtz Date: Thu, 5 Nov 2015 00:10:34 +0100 Subject: [PATCH 4/8] Use chained then, force our implementation so it's called even if then not called --- src/Guzzle6Promise.php | 45 +++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/src/Guzzle6Promise.php b/src/Guzzle6Promise.php index 76481bf..0745187 100644 --- a/src/Guzzle6Promise.php +++ b/src/Guzzle6Promise.php @@ -28,44 +28,39 @@ class Guzzle6Promise implements Promise /** * @var Exception */ - private $error; + private $exception; public function __construct(PromiseInterface $promise) { - $this->promise = $promise; - $this->state = self::PENDING; - } - - /** - * {@inheritdoc} - */ - public function then(callable $onFulfilled = null, callable $onRejected = null) - { - $onFulfilledInternal = function ($response) use($onFulfilled) { + $this->promise = $promise->then(function ($response) { $this->response = $response; $this->state = self::FULFILLED; - return $onFulfilled($this->response); - }; - - $onRejectedInternal = function ($reason) use($onRejected) { + return $response; + }, function ($reason) { if (!($reason instanceof RequestException)) { - throw new \RuntimeException("Invalid reason"); + throw new \RuntimeException("Invalid reason"); } - $this->state = self::REJECTED; - $this->error = new Exception\NetworkException($reason->getMessage(), $reason->getRequest(), $reason); + $this->state = self::REJECTED; + $this->exception = new Exception\NetworkException($reason->getMessage(), $reason->getRequest(), $reason); if ($reason->hasResponse()) { - $this->error = new Exception\HttpException($reason->getMessage(), $reason->getRequest(), $reason->getResponse(), $reason); + $this->exception = new Exception\HttpException($reason->getMessage(), $reason->getRequest(), $reason->getResponse(), $reason); } - return $onRejected($this->error); - }; + throw $this->exception; + }); - $this->promise = $this->promise->then($onFulfilledInternal, $onRejectedInternal); + $this->state = self::PENDING; + } - return new static($this->promise); + /** + * {@inheritdoc} + */ + public function then(callable $onFulfilled = null, callable $onRejected = null) + { + return new static($this->promise->then($onFulfilled, $onRejected)); } /** @@ -92,13 +87,13 @@ public function getResponse() /** * {@inheritdoc} */ - public function getError() + public function getException() { if (self::REJECTED !== $this->state) { throw new \LogicException("Error not available for the current state"); } - return $this->error; + return $this->exception; } /** From 696de133e07f89b813f7854a403aec250ad66467 Mon Sep 17 00:00:00 2001 From: Joel Wurtz Date: Thu, 5 Nov 2015 00:32:33 +0100 Subject: [PATCH 5/8] Rebase to master, sync request use async and wait --- src/Guzzle6HttpAdapter.php | 49 +++----------- src/Guzzle6Promise.php | 67 ++++++++++++++----- ...st.php => Guzzle6PromiseExceptionTest.php} | 31 ++++----- 3 files changed, 77 insertions(+), 70 deletions(-) rename tests/{Guzzle6HttpAdapterExceptionTest.php => Guzzle6PromiseExceptionTest.php} (76%) diff --git a/src/Guzzle6HttpAdapter.php b/src/Guzzle6HttpAdapter.php index d863c51..fa0b1ac 100644 --- a/src/Guzzle6HttpAdapter.php +++ b/src/Guzzle6HttpAdapter.php @@ -13,11 +13,9 @@ use GuzzleHttp\Client; use GuzzleHttp\ClientInterface; use GuzzleHttp\Exception as GuzzleExceptions; +use GuzzleHttp\Promise\PromiseInterface; use Http\Client\Exception; -use Http\Client\Exception\HttpException; -use Http\Client\Exception\NetworkException; use Http\Client\Exception\RequestException; -use Http\Client\Exception\TransferException; use Http\Client\HttpAsyncClient; use Http\Client\HttpClient; use Psr\Http\Message\RequestInterface; @@ -45,13 +43,14 @@ public function __construct(ClientInterface $client = null) */ public function sendRequest(RequestInterface $request) { - try { - return $this->client->send($request); - } catch (GuzzleExceptions\SeekException $e) { - throw new RequestException($e->getMessage(), $request, $e); - } catch (GuzzleExceptions\GuzzleException $e) { - throw $this->handleException($e); + $promise = $this->sendAsyncRequest($request); + $promise->wait(); + + if ($promise->getState() == PromiseInterface::REJECTED) { + throw $promise->getException(); } + + return $promise->getResponse(); } /** @@ -59,36 +58,6 @@ public function sendRequest(RequestInterface $request) */ public function sendAsyncRequest(RequestInterface $request) { - return new Guzzle6Promise($this->client->sendAsync($request)); - } - - /** - * Converts a Guzzle exception into an Httplug exception. - * - * @param GuzzleExceptions\GuzzleException $exception - * - * @return Exception - */ - private function handleException(GuzzleExceptions\GuzzleException $exception) - { - if ($exception instanceof GuzzleExceptions\ConnectException) { - return new NetworkException($exception->getMessage(), $exception->getRequest(), $exception); - } - - if ($exception instanceof GuzzleExceptions\RequestException) { - // Make sure we have a response for the HttpException - if ($exception->hasResponse()) { - return new HttpException( - $exception->getMessage(), - $exception->getRequest(), - $exception->getResponse(), - $exception - ); - } - - return new RequestException($exception->getMessage(), $exception->getRequest(), $exception); - } - - return new TransferException($exception->getMessage(), 0, $exception); + return new Guzzle6Promise($this->client->sendAsync($request), $request); } } diff --git a/src/Guzzle6Promise.php b/src/Guzzle6Promise.php index 0745187..7984d2f 100644 --- a/src/Guzzle6Promise.php +++ b/src/Guzzle6Promise.php @@ -2,10 +2,11 @@ namespace Http\Adapter; -use GuzzleHttp\Exception\RequestException; +use GuzzleHttp\Exception as GuzzleExceptions; use GuzzleHttp\Promise\PromiseInterface; -use Http\Client\Exception; +use Http\Client\Exception as HttplugException; use Http\Client\Promise; +use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; class Guzzle6Promise implements Promise @@ -26,33 +27,34 @@ class Guzzle6Promise implements Promise private $response; /** - * @var Exception + * @var HttplugException */ private $exception; - public function __construct(PromiseInterface $promise) + /** + * @var RequestInterface + */ + private $request; + + public function __construct(PromiseInterface $promise, RequestInterface $request) { + $this->request = $request; + $this->state = self::PENDING; $this->promise = $promise->then(function ($response) { $this->response = $response; $this->state = self::FULFILLED; return $response; - }, function ($reason) { - if (!($reason instanceof RequestException)) { + }, function ($reason) use ($request) { + if (!($reason instanceof GuzzleExceptions\GuzzleException)) { throw new \RuntimeException("Invalid reason"); } - $this->state = self::REJECTED; - $this->exception = new Exception\NetworkException($reason->getMessage(), $reason->getRequest(), $reason); - - if ($reason->hasResponse()) { - $this->exception = new Exception\HttpException($reason->getMessage(), $reason->getRequest(), $reason->getResponse(), $reason); - } + $this->state = self::REJECTED; + $this->exception = $this->handleException($reason, $request); throw $this->exception; }); - - $this->state = self::PENDING; } /** @@ -60,7 +62,7 @@ public function __construct(PromiseInterface $promise) */ public function then(callable $onFulfilled = null, callable $onRejected = null) { - return new static($this->promise->then($onFulfilled, $onRejected)); + return new static($this->promise->then($onFulfilled, $onRejected), $this->request); } /** @@ -103,5 +105,40 @@ public function wait() { $this->promise->wait(false); } + + /** + * Converts a Guzzle exception into an Httplug exception. + * + * @param GuzzleExceptions\GuzzleException $exception + * @param RequestInterface $request + * + * @return Exception + */ + private function handleException(GuzzleExceptions\GuzzleException $exception, RequestInterface $request) + { + if ($exception instanceof GuzzleExceptions\SeekException) { + return new HttplugException\RequestException($exception->getMessage(), $request, $exception); + } + + if ($exception instanceof GuzzleExceptions\ConnectException) { + return new HttplugException\NetworkException($exception->getMessage(), $exception->getRequest(), $exception); + } + + if ($exception instanceof GuzzleExceptions\RequestException) { + // Make sure we have a response for the HttpException + if ($exception->hasResponse()) { + return new HttplugException\HttpException( + $exception->getMessage(), + $exception->getRequest(), + $exception->getResponse(), + $exception + ); + } + + return new HttplugException\RequestException($exception->getMessage(), $exception->getRequest(), $exception); + } + + return new HttplugException\TransferException($exception->getMessage(), 0, $exception); + } } \ No newline at end of file diff --git a/tests/Guzzle6HttpAdapterExceptionTest.php b/tests/Guzzle6PromiseExceptionTest.php similarity index 76% rename from tests/Guzzle6HttpAdapterExceptionTest.php rename to tests/Guzzle6PromiseExceptionTest.php index 05aa0fd..4d3f13f 100644 --- a/tests/Guzzle6HttpAdapterExceptionTest.php +++ b/tests/Guzzle6PromiseExceptionTest.php @@ -12,56 +12,57 @@ namespace Http\Adapter\Tests; use GuzzleHttp\Exception as GuzzleExceptions; -use Http\Adapter\Guzzle6HttpAdapter; +use Http\Adapter\Guzzle6Promise; /** * @author Tobias Nyholm */ -class Guzzle6HttpAdapterExceptionTest extends \PHPUnit_Framework_TestCase +class Guzzle6PromiseExceptionTest extends \PHPUnit_Framework_TestCase { public function testGetException() { $request = $this->getMock('Psr\Http\Message\RequestInterface'); $response = $this->getMock('Psr\Http\Message\ResponseInterface'); + $promise = $this->getMock('GuzzleHttp\Promise\PromiseInterface'); - $adapter = new Guzzle6HttpAdapter(); - $method = new \ReflectionMethod('Http\Adapter\Guzzle6HttpAdapter', 'handleException'); + $adapter = new Guzzle6Promise($promise, $request); + $method = new \ReflectionMethod('Http\Adapter\Guzzle6Promise', 'handleException'); $method->setAccessible(true); - $outputException = $method->invoke($adapter, new GuzzleExceptions\ConnectException('foo', $request)); + $outputException = $method->invoke($adapter, new GuzzleExceptions\ConnectException('foo', $request), $request); $this->assertInstanceOf('Http\Client\Exception\NetworkException', $outputException, "Guzzle's ConnectException should be converted to a NetworkException"); - $outputException = $method->invoke($adapter, new GuzzleExceptions\TooManyRedirectsException('foo', $request)); + $outputException = $method->invoke($adapter, new GuzzleExceptions\TooManyRedirectsException('foo', $request), $request); $this->assertInstanceOf('Http\Client\Exception\RequestException', $outputException, "Guzzle's TooManyRedirectsException should be converted to a RequestException"); - $outputException = $method->invoke($adapter, new GuzzleExceptions\RequestException('foo', $request, $response)); + $outputException = $method->invoke($adapter, new GuzzleExceptions\RequestException('foo', $request, $response), $request); $this->assertInstanceOf('Http\Client\Exception\HttpException', $outputException, "Guzzle's RequestException should be converted to a HttpException"); - $outputException = $method->invoke($adapter, new GuzzleExceptions\BadResponseException('foo', $request, $response)); + $outputException = $method->invoke($adapter, new GuzzleExceptions\BadResponseException('foo', $request, $response), $request); $this->assertInstanceOf('Http\Client\Exception\HttpException', $outputException, "Guzzle's BadResponseException should be converted to a HttpException"); - $outputException = $method->invoke($adapter, new GuzzleExceptions\ClientException('foo', $request, $response)); + $outputException = $method->invoke($adapter, new GuzzleExceptions\ClientException('foo', $request, $response), $request); $this->assertInstanceOf('Http\Client\Exception\HttpException', $outputException, "Guzzle's ClientException should be converted to a HttpException"); - $outputException = $method->invoke($adapter, new GuzzleExceptions\ServerException('foo', $request, $response)); + $outputException = $method->invoke($adapter, new GuzzleExceptions\ServerException('foo', $request, $response), $request); $this->assertInstanceOf('Http\Client\Exception\HttpException', $outputException, "Guzzle's ServerException should be converted to a HttpException"); - $outputException = $method->invoke($adapter, new GuzzleExceptions\TransferException('foo')); + $outputException = $method->invoke($adapter, new GuzzleExceptions\TransferException('foo'), $request); $this->assertInstanceOf('Http\Client\Exception\TransferException', $outputException, "Guzzle's TransferException should be converted to a TransferException"); /* * Test RequestException without response */ - $outputException = $method->invoke($adapter, new GuzzleExceptions\RequestException('foo', $request)); + $outputException = $method->invoke($adapter, new GuzzleExceptions\RequestException('foo', $request), $request); $this->assertInstanceOf('Http\Client\Exception\RequestException', $outputException, "Guzzle's RequestException with no response should be converted to a RequestException"); - $outputException = $method->invoke($adapter, new GuzzleExceptions\BadResponseException('foo', $request)); + $outputException = $method->invoke($adapter, new GuzzleExceptions\BadResponseException('foo', $request), $request); $this->assertInstanceOf('Http\Client\Exception\RequestException', $outputException, "Guzzle's BadResponseException with no response should be converted to a RequestException"); - $outputException = $method->invoke($adapter, new GuzzleExceptions\ClientException('foo', $request)); + $outputException = $method->invoke($adapter, new GuzzleExceptions\ClientException('foo', $request), $request); $this->assertInstanceOf('Http\Client\Exception\RequestException', $outputException, "Guzzle's ClientException with no response should be converted to a RequestException"); - $outputException = $method->invoke($adapter, new GuzzleExceptions\ServerException('foo', $request)); + $outputException = $method->invoke($adapter, new GuzzleExceptions\ServerException('foo', $request), $request); $this->assertInstanceOf('Http\Client\Exception\RequestException', $outputException, "Guzzle's ServerException with no response should be converted to a RequestException"); } } \ No newline at end of file From 4fa7901399b3e5ec6ea78c61a18ab4faf2865922 Mon Sep 17 00:00:00 2001 From: Joel Wurtz Date: Thu, 5 Nov 2015 00:33:13 +0100 Subject: [PATCH 6/8] Fix return phpdoc in handleExcption --- src/Guzzle6Promise.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Guzzle6Promise.php b/src/Guzzle6Promise.php index 7984d2f..47dad30 100644 --- a/src/Guzzle6Promise.php +++ b/src/Guzzle6Promise.php @@ -112,7 +112,7 @@ public function wait() * @param GuzzleExceptions\GuzzleException $exception * @param RequestInterface $request * - * @return Exception + * @return HttplugException */ private function handleException(GuzzleExceptions\GuzzleException $exception, RequestInterface $request) { From 70f24df643a4bd419108f80a615bf560cd67277f Mon Sep 17 00:00:00 2001 From: Joel Wurtz Date: Thu, 5 Nov 2015 01:07:17 +0100 Subject: [PATCH 7/8] Return reason if it's already a httplug exception --- src/Guzzle6Promise.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Guzzle6Promise.php b/src/Guzzle6Promise.php index 47dad30..4433fe5 100644 --- a/src/Guzzle6Promise.php +++ b/src/Guzzle6Promise.php @@ -46,6 +46,13 @@ public function __construct(PromiseInterface $promise, RequestInterface $request return $response; }, function ($reason) use ($request) { + if ($reason instanceof HttplugException) { + $this->state = self::REJECTED; + $this->exception = $reason; + + throw $this->exception; + } + if (!($reason instanceof GuzzleExceptions\GuzzleException)) { throw new \RuntimeException("Invalid reason"); } From daa9b2778168dedd022463ad6f6fcaafcbe73191 Mon Sep 17 00:00:00 2001 From: Joel Wurtz Date: Thu, 5 Nov 2015 14:03:37 +0100 Subject: [PATCH 8/8] Use httplug-async --- composer.json | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 0d756d9..3864297 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,8 @@ ], "require": { "php": ">=5.5.0", - "php-http/httplug": "dev-feature/async as 1.0.1", + "php-http/httplug": "dev-master", + "php-http/httplug-async": "^0.1", "guzzlehttp/guzzle": "^6.0" }, "require-dev": { @@ -24,10 +25,6 @@ "php-http/adapter-integration-tests": "dev-feature/async-test" }, "repositories": [ - { - "type": "vcs", - "url": "https://github.com/joelwurtz/httplug" - }, { "type": "vcs", "url": "https://github.com/joelwurtz/adapter-integration-tests"