caseyamcl / guzzle_retry_middleware

Middleware for Guzzle v6/7+ that automatically retries HTTP requests on 429, 503 responses.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Suggestion: include exception in on_retry_callback

ViktorCollin opened this issue · comments

Detailed description

It would be useful for logging and reporting reasons to know get access to the exception that caused the retry in the on_retry_callback. I have not found a way to log what type of error that caused a retry due to a ConnectException.

Context

my setup looks like this:

GuzzleRetryMiddleware::factory([
    'max_retry_attempts' => 5,
    'give_up_after_secs' => 20,
    'retry_on_status' => [429, 500, 502, 503, 504],
    // This is not only timeouts, it is all ConnectException (https://github.com/caseyamcl/guzzle_retry_middleware/blob/v2.9.0/src/GuzzleRetryMiddleware.php#L239C55)
    'retry_on_timeout' => true,
    'on_retry_callback' => function (int $attemptNumber, float $delay, RequestInterface &$request, array &$options, ?ResponseInterface $response) {
        $maxAttempt = $options['max_retry_attempts'];
        $cause = $response ? "response status: {$response->getStatusCode()}" : 'Unknown cause';
        $this->logger->warning("Retrying request ($attemptNumber/$maxAttempt) in {$delay}ms. cause: $cause");
    }
])

As you can see i'm forces to log Unknown cause if a ConnectException occurred as there is no response in that case.

Possible implementation

One possible solution could be to change the signature of the doRetry function to something like this:

/**
 * Retry the request
 *
 * Increments the retry count, determines the delay (timeout), executes callbacks, sleeps, and re-sends the request
 *
 * @param RequestInterface $request
 * @param array<string,mixed> $options
 * @param ResponseInterface|null $response
 * @param RequestException|null $exception
 * @return Promise
 */
protected function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null, RequestException $exception = null): Promise

using GuzzleHttp\Exception\RequestException as that includes both BadResponseException and ConnectException

I can help with the implementation if you think that it is a good idea