Promise.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <?php
  2. namespace Http\Adapter\Guzzle6;
  3. use GuzzleHttp\Exception as GuzzleExceptions;
  4. use GuzzleHttp\Promise\PromiseInterface;
  5. use Http\Client\Exception as HttplugException;
  6. use Http\Promise\Promise as HttpPromise;
  7. use Psr\Http\Message\RequestInterface;
  8. use Psr\Http\Message\ResponseInterface;
  9. /**
  10. * Wrapper around Guzzle promises.
  11. *
  12. * @author Joel Wurtz <joel.wurtz@gmail.com>
  13. */
  14. class Promise implements HttpPromise
  15. {
  16. /**
  17. * @var PromiseInterface
  18. */
  19. private $promise;
  20. /**
  21. * @var string State of the promise
  22. */
  23. private $state;
  24. /**
  25. * @var ResponseInterface
  26. */
  27. private $response;
  28. /**
  29. * @var HttplugException
  30. */
  31. private $exception;
  32. /**
  33. * @var RequestInterface
  34. */
  35. private $request;
  36. /**
  37. * @param PromiseInterface $promise
  38. * @param RequestInterface $request
  39. */
  40. public function __construct(PromiseInterface $promise, RequestInterface $request)
  41. {
  42. $this->request = $request;
  43. $this->state = self::PENDING;
  44. $this->promise = $promise->then(function ($response) {
  45. $this->response = $response;
  46. $this->state = self::FULFILLED;
  47. return $response;
  48. }, function ($reason) use ($request) {
  49. $this->state = self::REJECTED;
  50. if ($reason instanceof HttplugException) {
  51. $this->exception = $reason;
  52. } elseif ($reason instanceof GuzzleExceptions\GuzzleException) {
  53. $this->exception = $this->handleException($reason, $request);
  54. } elseif ($reason instanceof \Exception) {
  55. $this->exception = new \RuntimeException('Invalid exception returned from Guzzle6', 0, $reason);
  56. } else {
  57. $this->exception = new \UnexpectedValueException('Reason returned from Guzzle6 must be an Exception', 0, $reason);
  58. }
  59. throw $this->exception;
  60. });
  61. }
  62. /**
  63. * {@inheritdoc}
  64. */
  65. public function then(callable $onFulfilled = null, callable $onRejected = null)
  66. {
  67. return new static($this->promise->then($onFulfilled, $onRejected), $this->request);
  68. }
  69. /**
  70. * {@inheritdoc}
  71. */
  72. public function getState()
  73. {
  74. return $this->state;
  75. }
  76. /**
  77. * {@inheritdoc}
  78. */
  79. public function wait($unwrap = true)
  80. {
  81. $this->promise->wait(false);
  82. if ($unwrap) {
  83. if ($this->getState() == self::REJECTED) {
  84. throw $this->exception;
  85. }
  86. return $this->response;
  87. }
  88. }
  89. /**
  90. * Converts a Guzzle exception into an Httplug exception.
  91. *
  92. * @param GuzzleExceptions\GuzzleException $exception
  93. * @param RequestInterface $request
  94. *
  95. * @return HttplugException
  96. */
  97. private function handleException(GuzzleExceptions\GuzzleException $exception, RequestInterface $request)
  98. {
  99. if ($exception instanceof GuzzleExceptions\SeekException) {
  100. return new HttplugException\RequestException($exception->getMessage(), $request, $exception);
  101. }
  102. if ($exception instanceof GuzzleExceptions\ConnectException) {
  103. return new HttplugException\NetworkException($exception->getMessage(), $exception->getRequest(), $exception);
  104. }
  105. if ($exception instanceof GuzzleExceptions\RequestException) {
  106. // Make sure we have a response for the HttpException
  107. if ($exception->hasResponse()) {
  108. return new HttplugException\HttpException(
  109. $exception->getMessage(),
  110. $exception->getRequest(),
  111. $exception->getResponse(),
  112. $exception
  113. );
  114. }
  115. return new HttplugException\RequestException($exception->getMessage(), $exception->getRequest(), $exception);
  116. }
  117. return new HttplugException\TransferException($exception->getMessage(), 0, $exception);
  118. }
  119. }