PHPackages                             slashequip/attempt - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. slashequip/attempt

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

slashequip/attempt
==================

Attempt is a simple, fluent class for attempting to run code multiple times whilst handling exceptions.

1.0.0(4y ago)43[1 issues](https://github.com/slashequip/attempt/issues)MITPHPPHP ^8.0

Since Jun 30Pushed 4y ago1 watchersCompare

[ Source](https://github.com/slashequip/attempt)[ Packagist](https://packagist.org/packages/slashequip/attempt)[ RSS](/packages/slashequip-attempt/feed)WikiDiscussions master Synced 4w ago

READMEChangelog (2)Dependencies (2)Versions (3)Used By (0)

Attempt
=======

[](#attempt)

Attempt is a simple, fluent class for attempting to run code multiple times whilst handling exceptions. It attempts to mimic PHPs built-in try/catch syntax where possible but sprinkles in some additional magic on top.

Installation
------------

[](#installation)

Attempt has been added to packagist and can be installed via composer:

```
composer require slashequip/attempt

```

Getting an instance
-------------------

[](#getting-an-instance)

Depending on your preference you can grab an Attempt instance in a couple of ways:

```
use SlashEquip\Attempt\Attempt;

$attempt = new Attempt();

$attempt = Attempt::make();
```

Building your Attempt
---------------------

[](#building-your-attempt)

Once you have your instance you can begin to build your Attempt.

### Try

[](#try)

This is the only required method, the `try` method accepts a callable argument, the code that you want to run.

```
$attempt
    ->try(function () {
        // My code that may or may not work.
    })
    ->thenReturn();
```

### Then Return

[](#then-return)

You may have noticed in the example above the method `thenReturn`, this method is what tells the Attempt to run. It will also return the value you return from the callable you pass to the `try` method.

There is also a `then` method, this too accepts a callable which is executed and passed the value returned by your `try` callable.

If it's your kind of jam, an attempt is also invokable which means at any point you can invoke the Attempt and it will run.

```
// $valueOne will be true
$valueOne = $attempt
    ->try(function () {
        return true;
    })
    ->thenReturn();

// $valueTwo will be false
$valueTwo = $attempt
    ->try(function () {
        return true;
    })
    ->then(function ($result) {
        return !$result;
    });

// $valueThree will be true
$valueThree = $attempt
    ->try(function () {
        return true;
    })();
```

### Times

[](#times)

You can set the amount of times the Attempt should be made whilst an exception is being encountered [see catch](#catch).

```
$valueOne = $attempt
    ->try(function () {
        throw new RuntimeException();
    })
    ->times(5)
    ->thenReturn();
// The above code would be run 5 times before throwing the RuntimeException
```

### Catch

[](#catch)

The `catch` method allows you to define exceptions you are expecting to encounter during the attempts, when exceptions have been passed to the catch method the Attempt will throw any other types of exceptions it comes across *early* rather than performing all attempts.

The `catch` method can be called multiple times to add multiple expected exceptions.

*If you do not provide any expected exception via the `catch` method then the Attempt will ignore all exceptions until all attempts have been made.*

```
$attempt
    ->try(function () {
        throw new UnexpectedException;
    })
    ->catch(TheExceptionWeAreExpecting::class)
    ->catch(AnotherExceptionWeAreExpecting::class)
    ->thenReturn();

// In this example; only one attempt would be made and a UnexpectedException would be thrown
```

The `catch` method also allows you to define a callback that will be called when the specified exception is eventually thrown. This can be useful for error logging or you could also return a default value if your code is to continue.

```
$attempt
    ->try(function () {
        throw new AnExpectedException;
    })
    ->catch(AnExpectedException::class, function (AnExpectedException $e) {
        error_log($e->getMessage());
        return new NullBlogPost();
    })
    ->thenReturn();
```

### No Throw

[](#no-throw)

Attempt can be configured to never throw exceptions, there are situations when you want to execute some code but still continue with the rest of your logic. For these situations you can use `noThrow`.

```
$attempt
    ->try(function () {
        throw new RuntimeException();
    })
    ->noThrow()
    ->thenReturn();
// The above exception would not bubble up and instead, simply, be swallowed.
```

### Finally

[](#finally)

The `finally` method allows you to run a callback at the end of the attempt *no matter the result*, whether the attempt was successful or an exception was thrown the `finally` callback will always be run.

```
$attempt
    ->try(function () {
        throw new UnexpectedException;
    })
    ->finally(function () {
        // run some clean up.
    })
    ->thenReturn();

// In this example; the finally callback would be run before the UnexpectedException is thrown
```

### Wait Between

[](#wait-between)

The `waitBetween` method takes an integer indicating the desired number of milliseconds to wait between attempts. The pause happens before the code runs but does not delay the starting of the Attempt.

```
$attempt
    ->try(function () use ($data) {
        throw new UnexpectedException;
    })
    ->times(3)
    ->waitBetween(250)
    ->thenReturn();

// In this example, there would be a pause of 250 milliseconds between each attempt.
```

Example use case
----------------

[](#example-use-case)

```
use SlashEquip\Attempt\Attempt;
use GuzzleHttp\Exception\ClientException;

$blogPost = Attempt::make()
    ->try(function () use ($data) {
        return UnstableBlogApiServiceUsingGuzzle::post([
           'data' => $data,
        ]);
    })
    ->times(3)
    ->waitBetween(250)
    ->catch(ClientException::class, function (ClientException $e) {
        error_log("Unstable blog api service is causing issues again.")
        return new BlogPost::nullableObject();
    })
    ->then(function ($apiResponse) {
        return BlogPost::fromApiResponse($apiResponse);
    });
```

###  Health Score

25

—

LowBetter than 37% of packages

Maintenance15

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity61

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~564 days

Total

2

Last Release

1574d ago

Major Versions

0.1.0 → 1.0.02022-01-16

PHP version history (2 changes)0.1.0PHP ^7.2

1.0.0PHP ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/fbb854e09eb0aafbd7b8dc4517599ced8da6b8528c9d4ddfe82a4fc9691e8796?d=identicon)[slashequip](/maintainers/slashequip)

---

Top Contributors

[![slashequip](https://avatars.githubusercontent.com/u/2316916?v=4)](https://github.com/slashequip "slashequip (10 commits)")

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/slashequip-attempt/health.svg)

```
[![Health](https://phpackages.com/badges/slashequip-attempt/health.svg)](https://phpackages.com/packages/slashequip-attempt)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
