From 7727489b1132e74fa0d2ccd02fa0e6fe10cbd245 Mon Sep 17 00:00:00 2001 From: Joel Wurtz Date: Mon, 28 May 2018 13:29:52 +0200 Subject: [PATCH] Add an option to only throw exception on 5XX error codes (#100) Add an option to only throw exception on 5XX error codes --- CHANGELOG.md | 4 ++++ spec/Plugin/ErrorPluginSpec.php | 16 ++++++++++++++++ src/Plugin/ErrorPlugin.php | 28 +++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa9039a..4c31194 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## 1.8 (unreleased) +### Added + + - Add an option on ErrorPlugin to only throw exception on response with 5XX status code. + ### Changed - AddPathPlugin no longer add prefix multiple times if a request is restarted - it now only adds the prefix if that request chain has not yet passed through the AddPathPlugin diff --git a/spec/Plugin/ErrorPluginSpec.php b/spec/Plugin/ErrorPluginSpec.php index de17ca4..20fcc25 100644 --- a/spec/Plugin/ErrorPluginSpec.php +++ b/spec/Plugin/ErrorPluginSpec.php @@ -36,6 +36,22 @@ function it_throw_client_error_exception_on_4xx_error(RequestInterface $request, $promise->shouldThrow('Http\Client\Common\Exception\ClientErrorException')->duringWait(); } + function it_does_not_throw_client_error_exception_on_4xx_error_if_only_server_exception(RequestInterface $request, ResponseInterface $response) + { + $this->beConstructedWith(['only_server_exception' => true]); + + $response->getStatusCode()->willReturn('400'); + $response->getReasonPhrase()->willReturn('Bad request'); + + $next = function (RequestInterface $receivedRequest) use($request, $response) { + if (Argument::is($request->getWrappedObject())->scoreArgument($receivedRequest)) { + return new HttpFulfilledPromise($response->getWrappedObject()); + } + }; + + $this->handleRequest($request, $next, function () {})->shouldReturnAnInstanceOf('Http\Client\Promise\HttpFulfilledPromise'); + } + function it_throw_server_error_exception_on_5xx_error(RequestInterface $request, ResponseInterface $response) { $response->getStatusCode()->willReturn('500'); diff --git a/src/Plugin/ErrorPlugin.php b/src/Plugin/ErrorPlugin.php index f09d3b1..bcc1c67 100644 --- a/src/Plugin/ErrorPlugin.php +++ b/src/Plugin/ErrorPlugin.php @@ -7,6 +7,7 @@ use Http\Client\Common\Plugin; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; /** * Throw exception when the response of a request is not acceptable. @@ -17,6 +18,31 @@ */ final class ErrorPlugin implements Plugin { + /** + * @var bool Whether this plugin should only throw 5XX Exceptions (default to false). + * + * If set to true 4XX Responses code will never throw an exception + */ + private $onlyServerException; + + /** + * @param array $config { + * + * @var bool only_server_exception Whether this plugin should only throw 5XX Exceptions (default to false). + * } + */ + public function __construct(array $config = []) + { + $resolver = new OptionsResolver(); + $resolver->setDefaults([ + 'only_server_exception' => false, + ]); + $resolver->setAllowedTypes('only_server_exception', 'bool'); + $options = $resolver->resolve($config); + + $this->onlyServerException = $options['only_server_exception']; + } + /** * {@inheritdoc} */ @@ -42,7 +68,7 @@ public function handleRequest(RequestInterface $request, callable $next, callabl */ protected function transformResponseToException(RequestInterface $request, ResponseInterface $response) { - if ($response->getStatusCode() >= 400 && $response->getStatusCode() < 500) { + if (!$this->onlyServerException && $response->getStatusCode() >= 400 && $response->getStatusCode() < 500) { throw new ClientErrorException($response->getReasonPhrase(), $request, $response); }