Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[9.x] Added 'throw' method to PendingRequest #41953

Merged
merged 3 commits into from
Apr 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Illuminate/Http/Client/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
* @method \Illuminate\Http\Client\PendingRequest withUserAgent(string $userAgent)
* @method \Illuminate\Http\Client\PendingRequest withoutRedirecting()
* @method \Illuminate\Http\Client\PendingRequest withoutVerifying()
* @method \Illuminate\Http\Client\PendingRequest throw(callable $callback = null)
* @method array pool(callable $callback)
* @method \Illuminate\Http\Client\Response delete(string $url, array $data = [])
* @method \Illuminate\Http\Client\Response get(string $url, array|string|null $query = null)
Expand Down
24 changes: 24 additions & 0 deletions src/Illuminate/Http/Client/PendingRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ class PendingRequest
*/
protected $options = [];

/**
* A callback to run when throwing if a server or client error occurs.
*
* @var \Closure
*/
protected $throwCallback;

/**
* The number of times to try the request.
*
Expand Down Expand Up @@ -547,6 +554,19 @@ public function beforeSending($callback)
});
}

/**
* Throw an exception if a server or client error occurs.
*
* @param callable|null $callback
* @return $this
*/
public function throw(callable $callback = null)
{
$this->throwCallback = $callback ?: fn () => null;

return $this;
}

/**
* Dump the request before sending.
*
Expand Down Expand Up @@ -726,6 +746,10 @@ public function send(string $method, string $url, array $options = [])
throw $exception;
}

if ($this->throwCallback) {
$response->throw($this->throwCallback);
}

if ($attempt < $this->tries && $shouldRetry) {
$response->throw();
}
Expand Down
1 change: 1 addition & 0 deletions src/Illuminate/Support/Facades/Http.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
* @method static \Illuminate\Http\Client\PendingRequest withUserAgent(string $userAgent)
* @method static \Illuminate\Http\Client\PendingRequest withoutRedirecting()
* @method static \Illuminate\Http\Client\PendingRequest withoutVerifying()
* @method static \Illuminate\Http\Client\PendingRequest throw(callable $callback = null)
* @method static array pool(callable $callback)
* @method static \Illuminate\Http\Client\Response delete(string $url, array $data = [])
* @method static \Illuminate\Http\Client\Response get(string $url, array|string|null $query = null)
Expand Down
59 changes: 59 additions & 0 deletions tests/Http/HttpClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1386,4 +1386,63 @@ public function testMiddlewareRunsWhenFaked()

$this->assertSame(['hyped-for' => 'laravel-movie'], json_decode(tap($history[0]['request']->getBody())->rewind()->getContents(), true));
}

public function testRequestExceptionIsNotThrownIfThePendingRequestIsSetToThrowOnFailureButTheResponseIsSuccessful()
{
$this->factory->fake([
'*' => $this->factory->response(['success'], 200),
]);

$response = $this->factory
->throw()
->get('http://foo.com/get');

$this->assertSame(200, $response->status());
}

public function testRequestExceptionIsThrownIfThePendingRequestIsSetToThrowOnFailure()
{
$this->factory->fake([
'*' => $this->factory->response(['error'], 403),
]);

$exception = null;

try {
$this->factory
->throw()
->get('http://foo.com/get');
} catch (RequestException $e) {
$exception = $e;
}

$this->assertNotNull($exception);
$this->assertInstanceOf(RequestException::class, $exception);
}

public function testRequestExceptionIsThrownWithCallbackIfThePendingRequestIsSetToThrowOnFailure()
{
$this->factory->fake([
'*' => $this->factory->response(['error'], 403),
]);

$exception = null;

$flag = false;

try {
$this->factory
->throw(function ($exception) use (&$flag) {
$flag = true;
})
->get('http://foo.com/get');
} catch (RequestException $e) {
$exception = $e;
}

$this->assertTrue($flag);

$this->assertNotNull($exception);
$this->assertInstanceOf(RequestException::class, $exception);
}
}