PHPackages                             catpaw/unsafe - 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. [Debugging &amp; Profiling](/categories/debugging)
4. /
5. catpaw/unsafe

ActiveLibrary[Debugging &amp; Profiling](/categories/debugging)

catpaw/unsafe
=============

Manage errors using Unsafe&lt;T&gt;

1.0.4(2y ago)18MITPHP

Since Feb 13Pushed 2y ago1 watchersCompare

[ Source](https://github.com/tncrazvan/catpaw-unsafe)[ Packagist](https://packagist.org/packages/catpaw/unsafe)[ RSS](/packages/catpaw-unsafe/feed)WikiDiscussions master Synced today

READMEChangelogDependencies (2)Versions (6)Used By (0)

Install with

```
composer require catpaw/unsafe
```

Control flow is king
====================

[](#control-flow-is-king)

I am of the opinion that control flow is one of the most important things to deal with as a programmer, it affects my thinking and at times it actually guides my problem solving process.

Managing errors should not break the flow in which I control my program, I shouldn't have to jump up and down around my file to catch a new exception introduced by a new function I just invoked 20 lines above.

Try/Catch
=========

[](#trycatch)

I found myself relying way too much on code like this

```
try {
    // some code
} catch(SomeException1 $e){
    // manage error 1
} catch(SomeException2 $e) {
    // manage error 2
} catch(SomeException3 $e) {
    // manage error 3
}
```

or even

```
try {
    // some code
} catch(SomeException1|SomeException2|SomeException3 $e){
    // manage all errors in one place
}
```

The last one might make sense in theory, but in practice those exceptions might each mean something different, a different cause for an error.

The reality is that very often I lump those exceptions in together because I forget to manage them or because for some reason at 4 AM I decide on the spot "yes, I should let my IDE dictate my error management".

Try/catch error handling has been (probably) the most popular way to manage errors in php, and I think it still is a valid way of dealing with errors in a global scope.

I can't argue there is something nice about having one centralized place to manage all errors, but I don't want to be forced to approach error management all the time in that manner.

If you're anything like me you might prefer managing your error inline, directly at the source, so that you deal with it when it pops up and then you don't have to think about it anymore.

Unsafe
======

[](#unsafe)

I have a solution.

Do not throw exceptions in your code, instead return your errors as *Unsafe*.

```
namespace CatPaw\Unsafe;
/**
 * @template T
 */
readonly class Unsafe {
    /** @var T $value */
    public $value;
    public false|Error $error;
}
```

Use the *ok()* and *error()* functions to create *Unsafe* objects.

ok()
====

[](#ok)

```
namespace CatPaw\Unsafe;
/**
 * @template T
 * @param T $value
 * @return Unsafe
 */
function ok($value);
```

Return *ok($value)* whenever there are no errors in your program.

This function will create a new *Unsafe* with a valid *$value* and no error.

error()
=======

[](#error)

```
namespace CatPaw\Core;
/**
 * @param string|Error $error
 * @return Unsafe
 */
function error($error);
```

Return *error($error)* whenever you encounter an error in your program and want to propagate it upstream.

This function will create a new *Unsafe* with a *null $value* and the given *error*.

Example
=======

[](#example)

The following example tries to read the contents of a file while managing errors.

First I'm declaring all entities involved, classes and functions.

```
