tetthys/domain-kernel

There is no license information available for the latest version (0.0.2) of this package.

Domain exception and error reason kernel for Tetthys ecosystem.

Installs: 2

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/tetthys/domain-kernel

0.0.2 2025-12-11 10:48 UTC

This package is auto-updated.

Last update: 2025-12-11 10:49:14 UTC


README

This guide shows the absolute minimum needed to use:

  • FailureReason enum
  • ServiceFailureException
  • ServiceFailable + abortWith()
  • A simple service (ItemService)

No framework. No repository layer. No external dependencies.

1. Directory Layout

src/
  Exceptions/
    ItemFailureReason.php
    ItemFailure.php
  Service/
    ItemService.php
example.php

That’s all you need.

2. File: src/Exceptions/ItemFailureReason.php

<?php

declare(strict_types=1);

namespace App\Exceptions;

use Tetthys\DomainKernel\ServiceFailureReason;

/**
 * Failure reasons for ItemService.
 */
enum ItemFailureReason: string implements ServiceFailureReason
{
    case NEGATIVE_PRICE = 'negative_price';

    public function code(): string
    {
        return $this->value;
    }

    public function message(): string
    {
        return match ($this) {
            self::NEGATIVE_PRICE => 'Price cannot be negative.',
        };
    }
}

3. File: src/Exceptions/ItemFailure.php

<?php

declare(strict_types=1);

namespace App\Exceptions;

use Tetthys\DomainKernel\ServiceFailureException;

/**
 * Single failure type for ItemService.
 */
final class ItemFailure extends ServiceFailureException
{
}

4. File: src/Service/ItemService.php

<?php

declare(strict_types=1);

namespace App\Service;

use App\Exceptions\ItemFailure;
use App\Exceptions\ItemFailureReason;
use Tetthys\DomainKernel\ServiceFailable;
use Tetthys\DomainKernel.ServiceFailureException;
use Tetthys\DomainKernel.ServiceFailureReason;

/**
 * Minimal pure PHP service using abortWith().
 */
final class ItemService
{
    use ServiceFailable;

    /**
     * Required by ServiceFailable.
     */
    protected function newServiceFailure(
        ServiceFailureReason $reason,
        array $context = [],
    ): ServiceFailureException {
        /** @var ItemFailureReason $reason */
        return new ItemFailure($reason, $context);
    }

    public function calculatePrice(int $price): int
    {
        if ($price < 0) {
            $this->abortWith(
                ItemFailureReason::NEGATIVE_PRICE,
                ['given_price' => $price],
            );
        }

        return $price * 2; // some logic
    }
}

5. File: example.php

<?php

declare(strict_types=1);

use App\Service\ItemService;
use Tetthys\DomainKernel\ServiceFailureException;

require __DIR__ . '/vendor/autoload.php';

$service = new ItemService();

try {
    // This will fail because the price is negative.
    $value = $service->calculatePrice(-10);
    echo "Result: {$value}\n";
} catch (ServiceFailureException $e) {
    echo "Failure occurred!\n";
    echo "Reason:  {$e->reason->code()}\n";
    echo "Message: {$e->reason->message()}\n";
    echo "Context: " . json_encode($e->context(), JSON_PRETTY_PRINT) . "\n";
}

6. Running the Example

php example.php

Output:

Failure occurred!
Reason:  negative_price
Message: Price cannot be negative.
Context: {
    "reason": "negative_price",
    "given_price": -10
}

7. What You Actually Need

Only four things:

✔ A failure reason enum

✔ A service-specific failure exception

✔ A service class using ServiceFailable + abortWith()

✔ A try/catch around your service call

This is the smallest possible real-world usage example of tetthys/domain-kernel and can be directly applied to any other domain (OrderService, AuthService, etc.).