So, let's retry that?
Tags: laravel, php
Published: 2022-10-11 16:09:57

---
title: So, let's retry that?
published: true
date: 2022-09-24 13:08:35 UTC
tags: laravel, php
canonical_url: https://dberri.com/so-lets-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](https://laravel.com/docs/9.x/helpers#method-retry), `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);
}
```

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;
    });
}
```

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!