Skip to content

Commit

Permalink
Merge pull request #40 from Nicolai-/should_retry_request_argument
Browse files Browse the repository at this point in the history
Include RequestInterface as argument in should_retry_callback
  • Loading branch information
caseyamcl authored Sep 16, 2024
2 parents e2ddb58 + a518045 commit 4cd2cd0
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All Notable changes to `guzzle_retry_middleware` will be documented in this file

Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles.

## [Unreleased]
### Added
- Include RequestInterface as [`should_retry_callback` argument](./README.md#custom-retry-decision-logic) when triggered.

## [2.10.0] (2024-06-19)
### Added
- Include [`on_retry_callback` argument]() when triggered by `onRejected` (thanks @ViktorCollin)
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -429,17 +429,26 @@ consider a server that returns a `200` status code, but with a message body inst
you can use the `should_retry_callback` option to implement a callback method that returns `true` (should retry) or `false`
(should not retry).

Another use for this callback could be based on the request itself.
For example, you may only want to retry requests that have a specific header set.

It's important to note that the callback will be called only if all the following circumstances are true:

* The `retry_enabled` option is `true` (default: `true`)
* The number of retries has not exceeded the value set in `max_retry_attempts` (default: `10`)
* The total time elapsed is less than the `give_up_after_secs` value (default: _disabled_)

```php
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;


$callback = function (array $options, ?ResponseInterface $response = null): bool {
$callback = function (array $options, ?ResponseInterface $response, RequestInterface $request): bool {
// Only allow retries if x-header header is set
if(! $request->hasHeader('x-header')) {
return false;
}

// Response will be NULL in the event of a connection timeout, so your callback function
// will need to be able to handle that case
if (! $response) {
Expand Down
2 changes: 1 addition & 1 deletion src/GuzzleRetryMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ protected function shouldRetryHttpResponse(

// Has 'should_retry_callback' option?
case $options['should_retry_callback']:
return (bool) call_user_func($options['should_retry_callback'], $options, $response);
return (bool) call_user_func($options['should_retry_callback'], $options, $response, $request);

// No Retry-After header, and it is required? Give up!
// (note: this has to be after the 'should_retry_callback' case)
Expand Down
13 changes: 9 additions & 4 deletions tests/GuzzleRetryMiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\RequestOptions;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
Expand Down Expand Up @@ -1028,16 +1029,20 @@ public function testDecideCallback(): void
$stack = HandlerStack::create(new MockHandler($responses));
$stack->push(GuzzleRetryMiddleware::factory([
'max_allowable_timeout_secs' => 2,
'should_retry_callback' => function (array $options, ?ResponseInterface $response) {
return $response && $response->getStatusCode() !== 200;
},
'should_retry_callback' =>
function (array $options, ?ResponseInterface $response, RequestInterface $request) {
return $response
&& $response->getStatusCode() !== 200
&& $request->hasHeader('x-header')
;
},
'on_retry_callback' => function () use (&$numTotalRetries) {
$numTotalRetries++;
}
]));

$client = new Client(['handler' => $stack]);
$client->request('GET', '/');
$client->request('GET', '/', [RequestOptions::HEADERS => ['x-header' => '123']]);
$this->assertSame(3, $numTotalRetries);
}

Expand Down

0 comments on commit 4cd2cd0

Please sign in to comment.