PHPackages                             martyrer/throwless-php - 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. martyrer/throwless-php

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

martyrer/throwless-php
======================

A PHP library for exception-free error handling using the Result monad pattern

v1.0.1(1y ago)11MITPHPPHP ^8.2CI passing

Since Apr 18Pushed 1y ago1 watchersCompare

[ Source](https://github.com/Martyrer/throwless-php)[ Packagist](https://packagist.org/packages/martyrer/throwless-php)[ RSS](/packages/martyrer-throwless-php/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (5)Versions (3)Used By (0)

Throwless PHP
=============

[](#throwless-php)

A PHP implementation of the Result type pattern, inspired by Rust's `Result` and JavaScript's `neverthrow` library. This library provides a type-safe way to handle errors without relying on exceptions, making your code more predictable and easier to reason about.

Features
--------

[](#features)

- Type-safe error handling without exceptions
- Immutable Result type with `Ok` and `Err` variants
- Comprehensive set of methods for working with Results
- Pure functional programming approach
- PHP 8.2+ with strict typing support

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

[](#installation)

```
composer require martyrer/throwless-php
```

Available Methods
-----------------

[](#available-methods)

- [**Type Checking**](#type-checking)

    - [`isOk()`](#isok) - Check if the Result contains a success value
    - [`isErr()`](#iserr) - Check if the Result contains an error value
    - [`isOkAnd(callable $fn)`](#isokand) - Executes the closure and returns its result as a boolean if the result is Ok
    - [`isErrAnd(callable $fn)`](#iserrand) - Executes the closure and returns its result as a boolean if the result is Err
- [**Transformation**](#transformation-methods)

    - [`map(callable $fn)`](#map) - Transform the success value
    - [`mapErr(callable $fn)`](#maperr) - Transform the error value
    - [`andThen(callable $fn)`](#andthen) - Chain Result-returning operations
- [**Matching**](#matching)

    - [`match(callable $okFn, callable $errFn)`](#match) - Handle both success and error cases
- [**Inspection**](#inspection-methods)

    - [`inspect(callable $fn)`](#inspect) - Inspect the success value
    - [`inspectErr(callable $fn)`](#inspecterr) - Inspect the error value
- [**Unwrapping**](#unwrapping-methods)

    - [`unwrap()`](#unwrap) - Get the success value or throw
    - [`unwrapErr()`](#unwraperr) - Get the error value or throw
    - [`unwrapOr(mixed $default)`](#unwrapor) - Get the success value or a default
    - [`unwrapOrElse(callable $fn)`](#unwraporelse) - Get the success value or compute a default
    - [`unwrapOrDefault(DefaultValueProvider $provider)`](#unwrapordefault) - Get the success value or type's default
    - [`expect(string $msg)`](#expect) - Get the success value or throw with custom message
    - [`expectErr(string $msg)`](#expecterr) - Get the error value or throw with custom message
    - [`unwrapUnchecked()`](#unwrapunchecked) - Get the success value without checking (unsafe)
    - [`unwrapErrUnchecked()`](#unwraperrunchecked) - Get the error value without checking (unsafe)

Basic Usage
-----------

[](#basic-usage)

```
use Martyrer\Throwless\Ok;
use Martyrer\Throwless\Err;
use Martyrer\Throwless\Result;

// Creating Results
$success = new Ok(42); // Ok
$failure = new Err("something went wrong"); // Err

// Checking Result type
$success->isOk(); // true
$success->isErr(); // false
$failure->isOk(); // false
$failure->isErr(); // true

// Unwrapping values
$success->unwrap(); // 42
$failure->unwrapErr(); // "something went wrong"

// Using default values
$success->unwrapOr(0); // 42
$failure->unwrapOr(0); // 0
```

Core Methods
------------

[](#core-methods)

### Type Checking

[](#type-checking)

#### `isOk`

[](#isok)

Check if the Result contains a success value:

```
$result = new Ok(42);
$result->isOk(); // true

$error = new Err("failed");
$error->isOk(); // false
```

#### `isErr`

[](#iserr)

Check if the Result contains an error value:

```
$result = new Ok(42);
$result->isErr(); // false

$error = new Err("failed");
$error->isErr(); // true
```

#### `isOkAnd`

[](#isokand)

Check if Result is Ok and the value matches a predicate:

```
$result = new Ok(42);
$isEven = $result->isOkAnd(fn($x) => $x % 2 === 0); // true
$isNegative = $result->isOkAnd(fn($x) => $x < 0); // false
```

#### `isErrAnd`

[](#iserrand)

Check if Result is Err and the error matches a predicate:

```
$error = new Err("invalid input");
$isInputError = $error->isErrAnd(fn($e) => str_contains($e, "input")); // true
$isTimeout = $error->isErrAnd(fn($e) => str_contains($e, "timeout")); // false
```

### Transformation Methods

[](#transformation-methods)

#### `map`

[](#map)

Transform the success value while preserving the error:

```
$result = new Ok(5);
$doubled = $result->map(fn($x) => $x * 2); // Ok(10)

$error = new Err("failed");
$doubled = $error->map(fn($x) => $x * 2); // Err("failed")
```

#### `mapErr`

[](#maperr)

Transform the error value while preserving the success:

```
$result = new Err("error");
$mapped = $result->mapErr(fn($e) => "Error: " . $e); // Err("Error: error")

$success = new Ok(42);
$mapped = $success->mapErr(fn($e) => "Error: " . $e); // Ok(42)
```

#### `andThen`

[](#andthen)

Chain operations that might fail:

```
function divide($x, $y): Result {
    return $y === 0 ? new Err("division by zero") : new Ok($x / $y);
}

$result = new Ok(10)
    ->andThen(fn($x) => divide($x, 2)) // Ok(5)
    ->andThen(fn($x) => divide($x, 0)); // Err("division by zero")
```

### Matching

[](#matching)

#### `match`

[](#match)

Handle both success and error cases:

```
$result = new Ok(42);
$value = $result->match(
    fn($value) => "Success: $value",
    fn($error) => "Error: $error"
); // "Success: 42"
```

### Inspection Methods

[](#inspection-methods)

#### `inspect`

[](#inspect)

Perform side effects on success value without consuming the Result:

```
$result = new Ok(42);
$result->inspect(fn($value) => print("Got value: $value"))
       ->map(fn($x) => $x * 2);
```

#### `inspectErr`

[](#inspecterr)

Perform side effects on error value without consuming the Result:

```
$error = new Err("error");
$error->inspectErr(fn($err) => print("Error occurred: $err"))
      ->mapErr(fn($err) => "Handled: $err");
```

### Unwrapping Methods

[](#unwrapping-methods)

#### `unwrap`

[](#unwrap)

Get the success value or throw an exception:

```
$result = new Ok(42);
$value = $result->unwrap(); // 42

$error = new Err("oops");
$value = $error->unwrap(); // throws UnwrapException
```

#### `unwrapErr`

[](#unwraperr)

Get the error value or throw an exception:

```
$error = new Err("error message");
$value = $error->unwrapErr(); // "error message"

$success = new Ok(42);
$value = $success->unwrapErr(); // throws UnwrapException
```

#### `unwrapOr`

[](#unwrapor)

Get the value or a default:

```
$result = new Err("error");
$value = $result->unwrapOr(42); // 42
```

#### `unwrapOrElse`

[](#unwraporelse)

Get the value or compute a default:

```
$result = new Err("error");
$value = $result->unwrapOrElse(fn($error) => strlen($error)); // 5
```

#### `unwrapOrDefault`

[](#unwrapordefault)

Get the success value or the type's default value:

```
class DefaultProvider implements DefaultValueProvider {
    public function getDefault(): int {
        return 0;
    }
}

$result = new Err("error");
$value = $result->unwrapOrDefault(new DefaultProvider()); // 0
```

#### `expect`

[](#expect)

Unwrap with a custom error message:

```
$result = new Ok(42);
$value = $result->expect("This should never fail"); // 42

$error = new Err("oops");
$value = $error->expect("Critical error"); // throws UnwrapException with message "Critical error"
```

#### `expectErr`

[](#expecterr)

Get the error value with a custom error message:

```
$error = new Err("not found");
$value = $error->expectErr("Expected error not found"); // "not found"

$success = new Ok(42);
$value = $success->expectErr("Expected an error"); // throws UnwrapException with message "Expected an error"
```

#### `unwrapUnchecked`

[](#unwrapunchecked)

Get the success value without safety checks (use with caution):

```
// WARNING: Only use when you are absolutely certain the Result is Ok
// Otherwise, it will cause undefined behavior
$result = new Ok(42);
$value = $result->unwrapUnchecked(); // 42
```

#### `unwrapErrUnchecked`

[](#unwraperrunchecked)

Get the error value without safety checks (use with caution):

```
// WARNING: Only use when you are absolutely certain the Result is Err
// Otherwise, it will cause undefined behavior
$error = new Err("error");
$value = $error->unwrapErrUnchecked(); // "error"
```

Real-world Examples
-------------------

[](#real-world-examples)

### Example 1: User Authentication

[](#example-1-user-authentication)

```
class UserAuthenticator {
    public function authenticate(string $username, string $password): Result {
        $user = $this->findUser($username);

        if ($user === null) {
            return new Err("User not found");
        }

        return password_verify($password, $user->password)
            ? new Ok($user)
            : new Err("Invalid password");
    }
}

// Usage
$auth = new UserAuthenticator();
$result = $auth->authenticate("john", "password123")
    ->map(fn($user) => $user->toArray())
    ->mapErr(fn($error) => ["error" => $error]);
```

### Example 2: API Response Handling

[](#example-2-api-response-handling)

```
class ApiClient {
    public function fetchData(string $url): Result {
        try {
            $response = file_get_contents($url);
            $data = json_decode($response, true);

            return $data === null
                ? new Err("Invalid JSON response")
                : new Ok($data);
        } catch (Throwable $e) {
            return new Err($e->getMessage());
        }
    }
}

// Usage
$client = new ApiClient();
$result = $client->fetchData("https://api.example.com/data")
    ->andThen(function($data) {
        return isset($data['items'])
            ? new Ok($data['items'])
            : new Err("Missing items in response");
    })
    ->map(fn($items) => array_map(fn($item) => $item['name'], $items));
```

Contributing
------------

[](#contributing)

Contributions are welcome! Please feel free to submit a Pull Request. Make sure to read the contributing guidelines before submitting your PR.

License
-------

[](#license)

This project is licensed under the MIT License - see the LICENSE file for details.

###  Health Score

29

—

LowBetter than 59% of packages

Maintenance47

Moderate activity, may be stable

Popularity3

Limited adoption so far

Community4

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

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 ~0 days

Total

2

Last Release

394d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/0d3b17bcd8192d0f21b9a1e1f705d36a277c2d5c5ad41f80b290862dfe7f484b?d=identicon)[Martyrer](/maintainers/Martyrer)

---

Tags

phpexceptionsresultfunctionalerror handlingmonadrailway-oriented-programming

###  Code Quality

TestsPest

Static AnalysisPHPStan, Rector

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/martyrer-throwless-php/health.svg)

```
[![Health](https://phpackages.com/badges/martyrer-throwless-php/health.svg)](https://phpackages.com/packages/martyrer-throwless-php)
```

###  Alternatives

[lambdish/phunctional

λ PHP functional library

3612.0M23](/packages/lambdish-phunctional)[mpetrovich/dash

A functional programming library for PHP. Inspired by Underscore, Lodash, and Ramda.

10428.9k1](/packages/mpetrovich-dash)[chippyash/monad

Functional programming Monad support

2828.1k8](/packages/chippyash-monad)[krak/fn

Functional library for php with proper currying

2419.0k3](/packages/krak-fn)[transprime-research/piper

PHP Pipe method execution with values from chained method executions

174.6k2](/packages/transprime-research-piper)

PHPackages © 2026

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