Skip to content

Commit

Permalink
feat: add some readme notes
Browse files Browse the repository at this point in the history
  • Loading branch information
iliaamiri committed Oct 28, 2024
1 parent 7f23624 commit b9f8d07
Showing 1 changed file with 147 additions and 0 deletions.
147 changes: 147 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,150 @@
# Might Fail

A PHP library for handling errors without `try` and `catch` blocks.

## Installation

```bash
composer require might-fail/might-fail
```

### Import

Import `mightFail` function into your source files.

```php
use function MightFail\mightFail;
```

## Usage

### Example 1

Requesting data from an API in a laravel application.

Here's the try-catch way to do it.

```php
try {
$response = Http::withToken($secretToken)->post('https://example.com')->throw();
$json = $response->json();
if ($json === null) {
return response()->json(['error' => 'Invalid JSON.']);
}

return response()->json($json);
} catch (ConnectionException $e) {
return response()->json(['error' => 'Connection failed.']);
} catch (TimeoutException $e) {
return response()->json(['error' => 'Timeout.']);
} catch (HttpException $e) {
return response()->json(['error' => 'HTTP error.']);
} catch (Exception $e) {
return response()->json(['error' => 'Unknown error.']);
}
```

And, here's the `mightFail` way to do it.

```php
use function MightFail\mightFail;

$either = mightFail(fn () => Http::withToken($secretToken)->post('https://example.com')->throw());

// You can also destructure the object like a tuple, if you want.
[$error, $response] = $either;

if ($either->error) {
return match (get_class($either->error)) {
ConnectionException::class => response()->json(['error' => 'Connection failed.']),
TimeoutException::class => response()->json(['error' => 'Timeout.']),
HttpException::class => response()->json(['error' => 'HTTP error.']),
default => response()->json(['error' => 'Unknown error.']),
};
}

$response = $either->result;

$either = mightFail(fn () => User::findOrFail(1));

if ($either->error !== null) {
return response()->json([
'error' => 'User not found.',
]);
}
```

### Example 2

Calling a repository method that might fail.

Here's the classic try-catch way to do it.

```php
try {
$shop = ShopRepository::visit($id);

return response()->json([
'success' => true,
'data' => $shop,
]);
} catch (Exception $e) {
return response()->json([
'error' => 'Could not visit this shop',
]);
} finally {
logger()->info('User tried to visit a shop', [
'shop' => $shop,
// ...
]);
}
```

And, here's the `mightFail` way to do it.

```php
use function MightFail\mightFail;

[$error, $shop] = mightFail(fn () => ShopRepository::visit($id));

// Your finally block
logger()->info('User tried to visit a shop', [
'shop' => $shop,
// ...
]);

// Guard against error and handle it immediately
if ($error !== null) {
return response()->json([
'error' => 'Could not visit this shop',
]);
}

// Now we can safely return the shop
return response()->json([
'success' => true,
'data' => $shop,
]);
```

## Might and Fail

You can return `Might` or `Fail` classes from a method and natively return an `Either` type without `mightFail`
function.

```php
use MightFail\Either;
use MightFail\Fail;
use MightFail\Might;

public function visit(int $id): Either
{
// ...

if ($badThingHappened) {
return Fail::from(new Exception('Something went wrong.'));
}

return Might::from($shop);
}
```

0 comments on commit b9f8d07

Please sign in to comment.