diff --git a/src/Illuminate/Http/Client/Response.php b/src/Illuminate/Http/Client/Response.php index 2a34b5f83fef..f93dc6c753b2 100644 --- a/src/Illuminate/Http/Client/Response.php +++ b/src/Illuminate/Http/Client/Response.php @@ -216,6 +216,21 @@ public function throw() return $this; } + /** + * Execute the callback and throw an exception if a server of client error occurred. + * + * @param \Closure $callback + * @return $this + */ + public function onError($callback) + { + if ($this->serverError() || $this->clientError()) { + $callback($this); + } + + return $this; + } + /** * Determine if the given offset exists. * diff --git a/tests/Http/HttpClientTest.php b/tests/Http/HttpClientTest.php index 45aae46c950e..6a599b2fdb6d 100644 --- a/tests/Http/HttpClientTest.php +++ b/tests/Http/HttpClientTest.php @@ -476,6 +476,86 @@ public function testRequestExceptionEmptyBody() throw new RequestException(new Response($response)); } + public function testOnErrorDoesntCallClosureOnInformational() + { + $status = 0; + $client = $this->factory->fake([ + 'laravel.com' => $this->factory::response('', 101), + ]); + + $response = $client->get('laravel.com') + ->onError(function ($response) use (&$status) { + $status = $response->status(); + }); + + $this->assertSame(0, $status); + $this->assertSame(101, $response->status()); + } + + public function testOnErrorDoesntCallClosureOnSuccess() + { + $status = 0; + $client = $this->factory->fake([ + 'laravel.com' => $this->factory::response('', 201), + ]); + + $response = $client->get('laravel.com') + ->onError(function ($response) use (&$status) { + $status = $response->status(); + }); + + $this->assertSame(0, $status); + $this->assertSame(201, $response->status()); + } + + public function testOnErrorDoesntCallClosureOnRedirection() + { + $status = 0; + $client = $this->factory->fake([ + 'laravel.com' => $this->factory::response('', 301), + ]); + + $response = $client->get('laravel.com') + ->onError(function ($response) use (&$status) { + $status = $response->status(); + }); + + $this->assertSame(0, $status); + $this->assertSame(301, $response->status()); + } + + public function testOnErrorCallsClosureOnClientError() + { + $status = 0; + $client = $this->factory->fake([ + 'laravel.com' => $this->factory::response('', 401), + ]); + + $response = $client->get('laravel.com') + ->onError(function ($response) use (&$status) { + $status = $response->status(); + }); + + $this->assertSame(401, $status); + $this->assertSame(401, $response->status()); + } + + public function testOnErrorCallsClosureOnServerError() + { + $status = 0; + $client = $this->factory->fake([ + 'laravel.com' => $this->factory::response('', 501), + ]); + + $response = $client->get('laravel.com') + ->onError(function ($response) use (&$status) { + $status = $response->status(); + }); + + $this->assertSame(501, $status); + $this->assertSame(501, $response->status()); + } + public function testSinkToFile() { $this->factory->fakeSequence()->push('abc123');