Laravel retries around external calls
This example shows how to use the retrier to wrap flaky external calls (HTTP, queues, third-party APIs).
Service
php
namespace App\Services;
use Illuminate\Support\Facades\Log;
use Maxiviper117\ResultFlow\Result;
final class ShippingService
{
public function createLabel(array $payload): Result
{
return Result::retrier()
->maxAttempts(3)
->delay(200)
->exponential()
->when(fn ($error, $attempt) => $this->shouldRetry($error))
->onRetry(function ($attempt, $error, $wait) {
Log::warning('shipping.retry', [
'attempt' => $attempt,
'error' => (string) $error,
'wait_ms' => $wait,
]);
})
->attempt(fn () => $this->callCarrier($payload));
}
private function shouldRetry(mixed $error): bool
{
return $error instanceof \RuntimeException;
}
private function callCarrier(array $payload): array
{
// throw on transport error or return array payload
return ['label_id' => 'abc123'];
}
}Notes:
attempt()accepts raw values or Results. Raw values are wrapped asResult::ok.- Exceptions thrown by
callCarrier()become failures and are eligible for retries. - Keep the retry predicate narrow to avoid retrying validation errors.
Result functions used
retrier(),maxAttempts(),delay(),exponential(),when(),onRetry(),attempt()