3dgoo / laravel-http-timeout-retry-provider
Http timeout retry provider for Laravel
Requires
- php: ^8.1 || ^8.2 || ^8.3 || ^8.4
- illuminate/http: ^10.0 || ^11.0 || ^12.0
Requires (Dev)
- guzzlehttp/guzzle: ^7.9
- laravel/pint: ^1.20
- nunomaduro/collision: ^7.12 || ^8.0
- orchestra/testbench: ^8.36 || ^9.0
- overtrue/phplint: ^9.6
- pestphp/pest: ^2.36 || ^3.0
- pestphp/pest-plugin-laravel: ^2.4 || ^3.0
This package is auto-updated.
Last update: 2025-06-25 07:58:00 UTC
README
A Laravel package that adds retry functionality to Http requests with configurable timeout handling and HTTP method filtering.
Features
- Adds a
withTimeoutRetry()
macro to Laravel's HTTP client - Retries requests on
ConnectionException
(timeout) and other configurable exceptions - Http method filtering - Configure which methods (GET, POST, etc.) are safe to retry
- Configurable retry attempts, delay, and enable/disable via config or environment variables
- Optional logging of retry attempts with configurable log levels and channels
- Runtime parameter overrides for fine-grained control
Installation
Require the package via Composer:
composer require 3dgoo/laravel-http-timeout-retry-provider
The service provider will be auto-discovered by Laravel.
Configuration
You can publish the configuration file:
php artisan vendor:publish --provider="X3dgoo\HttpTimeoutRetryProvider\Providers\HttpTimeoutRetryProvider" --tag=config
Or, set the following environment variables in your .env file:
HTTP_RETRY_ENABLED=true HTTP_RETRY_ATTEMPTS=3 HTTP_RETRY_DELAY=100 HTTP_RETRY_ALLOWED_METHODS=GET,HEAD,OPTIONS HTTP_RETRY_LOGGING_ENABLED=false HTTP_RETRY_LOGGING_LEVEL=info HTTP_RETRY_LOGGING_CHANNEL=
Configuration Options
- HTTP_RETRY_ENABLED: Master switch to enable/disable retry functionality
- HTTP_RETRY_ATTEMPTS: Number of retry attempts (0-100)
- HTTP_RETRY_DELAY: Base delay between retries in milliseconds (minimum 10ms)
- HTTP_RETRY_ALLOWED_METHODS: Comma-separated list of HTTP methods allowed for retry
- HTTP_RETRY_LOGGING_ENABLED: Enable logging of retry attempts
- HTTP_RETRY_LOGGING_LEVEL: Log level for retry messages
- HTTP_RETRY_LOGGING_CHANNEL: Custom log channel (optional)
Usage
Basic Usage
Use the withTimeoutRetry()
macro on any HTTP client request:
use Illuminate\Support\Facades\Http; // Will retry GET requests (safe method) $response = Http::withTimeoutRetry()->get('https://api.example.com/data'); // Will NOT retry POST requests by default (unsafe method) $response = Http::withTimeoutRetry()->post('https://api.example.com/create', $data);
Advanced Usage with Parameters
Override default settings for specific requests:
Http::withTimeoutRetry( attempts: 5, delay: 250, callback: function ($exception) { return $exception instanceof \RuntimeException; }, logRetries: true, allowedMethods: ['POST', 'PUT'] )->post('https://api.example.com/create', $data);
HTTP Method Filtering
By default, only safe HTTP methods are retried to prevent unintended side effects:
// These methods are retried by default (safe, idempotent): Http::withTimeoutRetry()->get('https://api.example.com/data'); Http::withTimeoutRetry()->head('https://api.example.com/check'); Http::withTimeoutRetry()->options('https://api.example.com/'); // These methods are NOT retried by default (potentially unsafe): Http::withTimeoutRetry()->post('https://api.example.com/create'); Http::withTimeoutRetry()->put('https://api.example.com/update'); Http::withTimeoutRetry()->delete('https://api.example.com/item');
Overriding Method Filtering
When you need to retry unsafe methods, override at runtime:
// Allow specific methods for this request Http::withTimeoutRetry( allowedMethods: ['POST', 'PUT'] )->post('https://api.example.com/idempotent-create', $data); // Allow all methods for this request Http::withTimeoutRetry( allowedMethods: ['*'] )->delete('https://api.example.com/resource/123');
Method Safety Guide
Different HTTP methods have different safety characteristics:
✅ Safe Methods (Default retry enabled)
- GET, HEAD, OPTIONS: Idempotent and safe, no side effects
- These are the recommended defaults for retry
⚠️ Potentially Unsafe Methods (Require explicit opt-in)
- POST: Not idempotent, may create duplicate resources
- PUT: Idempotent by spec, but implementation varies
- PATCH: Not idempotent, partial updates can cause issues
- DELETE: Idempotent but potentially destructive
Configuration Examples
// Safe methods only (recommended default) 'allowed_methods' => ['GET', 'HEAD', 'OPTIONS'], // All read operations 'allowed_methods' => ['GET', 'HEAD', 'OPTIONS'], // Include idempotent write operations (use with caution) 'allowed_methods' => ['GET', 'HEAD', 'OPTIONS', 'PUT'], // All methods (not recommended as default) 'allowed_methods' => ['*'],
Logging
When logging is enabled, retry attempts are logged with detailed information including the HTTP method:
- Log Level: Configurable via
HTTP_RETRY_LOGGING_LEVEL
(default:info
) - Log Channel: Configurable via
HTTP_RETRY_LOGGING_CHANNEL
(uses default log channel if not set) - Log Message: Includes HTTP method, attempt number, total attempts, URL, and exception details
Example log entry:
[2025-06-25 12:00:00] local.info: HTTP GET request retry attempt 1/3 failed for URL https://api.example.com/create: Connection timeout
{
"attempt": 1,
"total_attempts": 3,
"exception_class": "Illuminate\\Http\\Client\\ConnectionException",
"exception_message": "Connection timeout",
"request_url": "https://api.example.com/create",
"request_method": "GET"
}
Configuration File
Default config (config/http.php):
return [ 'retry' => [ 'enabled' => env('HTTP_RETRY_ENABLED', true), 'attempts' => max(0, min(100, env('HTTP_RETRY_ATTEMPTS', 3))), 'delay' => max(10, env('HTTP_RETRY_DELAY', 100)), 'allowed_methods' => array_map('strtoupper', explode(',', env('HTTP_RETRY_ALLOWED_METHODS', 'GET,HEAD,OPTIONS'))), 'logging' => [ 'enabled' => env('HTTP_RETRY_LOGGING_ENABLED', false), 'level' => env('HTTP_RETRY_LOGGING_LEVEL', 'info'), 'channel' => env('HTTP_RETRY_LOGGING_CHANNEL', null), ], ], ];
License
MIT