DEV Community

David Berri
David Berri

Posted on • Originally published at dberri.com on

So, let's retry that?

A few weeks ago, I had to implement some code that would need to retry an operation with different parameters if it failed on the first run but only if it did with a specific exception. I thought about it for a few minutes and before I tried to implement it myself, I decided to search Laravel's documentation to see if there was a helper or something that I could use. Turns out there is a helper called: retry. Yes, it was exactly what I was looking for and more.

According to the docs, retry accepts the number of attempts, the callback where your implementation goes and a third (optional) parameter that can either be a number of milliseconds or a closure to change the time it will wait before the next attempt. It also accepts a fourth (also optional) parameter: a closure that returns the condition in which the method should retry. For example, if you want to retry only if a specific exception was thrown.

If the callback you implement throws an exception, the retry method will catch that and if it still has more attempts, it will retry, otherwise it will throw that exception. On the other hand, if your callback is successful, the retry method will return the value your callback returned. Very straightforward, huh?

Ok, now that you have an overview of how it works, let's see some code. As an example, let's create a function that gives you three chances of guessing a random number:

function guessTheNumber($num) {
    $value = rand(0, 10);
    if ($value === $num) {
        return true;
    }
    throw new \Exception('You guessed the wrong number!');
}

function tryYourLuck() {
    return retry(3, function() {
        return guessTheNumber(5);
    }, 100);
}
Enter fullscreen mode Exit fullscreen mode

The first function (guessTheNumber) accepts a value and compares it to a random one. If they are equal, return true, otherwise throw an exception. It is just a silly example to show how retry works. The second function (tryYourLuck) is where we call guessTheNumber with our guessed value (5) and since we have three chances, we call retry with 3 as the first parameter. Just to show you how it works, I'm also passing a third parameter to retry which is the amount of milliseconds the function should wait before retrying. Now, if we call tryYourLuck and it guessTheNumber returns true in any of the three attempts, tryYourLuck will also return true. But, if it retries three times and all of them threw an exception, then tryYourLuck will throw the last exception.

The feature that really helped me was the option to pass a closure as the fourth argument and use that to decide if we the method should retry. The closure accepts the exception as its first parameter, so we can do something like:

class MyException extends Exception { }

function guessTheNumber($num) {
    $value = rand(0, 10);
    if ($value === $num) {
        return true;
    }
    throw new MyException('You guessed the wrong number!');
}

function tryYourLuck() {
    return retry(3, function() {
        return guessTheNumber(5);
    }, 100, function($exception) {
        return $exception instanceof MyException;
    });
}
Enter fullscreen mode Exit fullscreen mode

Here we are telling the retry method that it should only retry if the exception if caught was MyException. If it catches any other exception, it should not retry at all.

And with that, I wrap up this blog post. Until next time!

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (0)

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

👋 Kindness is contagious

Immerse yourself in a wealth of knowledge with this piece, supported by the inclusive DEV Community—every developer, no matter where they are in their journey, is invited to contribute to our collective wisdom.

A simple “thank you” goes a long way—express your gratitude below in the comments!

Gathering insights enriches our journey on DEV and fortifies our community ties. Did you find this article valuable? Taking a moment to thank the author can have a significant impact.

Okay