PHPackages                             hradigital/php-exceptions - 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. hradigital/php-exceptions

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

hradigital/php-exceptions
=========================

PHP Domain Exceptions library — a curated set of reusable, semantic exceptions for Domain-Driven Design applications.

1.0.0(1mo ago)0231GPL-3.0-or-laterPHPPHP ^8.1CI passing

Since May 5Pushed 1mo agoCompare

[ Source](https://github.com/HRADigital/php-exceptions)[ Packagist](https://packagist.org/packages/hradigital/php-exceptions)[ Docs](https://github.com/HRADigital/php-exceptions)[ RSS](/packages/hradigital-php-exceptions/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (1)Dependencies (1)Versions (2)Used By (1)

php-exceptions
==============

[](#php-exceptions)

[![Latest Version on Packagist](https://camo.githubusercontent.com/c9b5c776a9b85dc99b83653ab95f9968f7135a7decbf2a060493918d034354e8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6872616469676974616c2f7068702d657863657074696f6e732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/hradigital/php-exceptions)[![CI](https://github.com/HRADigital/php-exceptions/actions/workflows/ci.yml/badge.svg)](https://github.com/HRADigital/php-exceptions/actions/workflows/ci.yml)[![Total Downloads](https://camo.githubusercontent.com/749438ae1df3c96e3dd675b3957426f0fddf669988451e90725c381e3b224e41/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6872616469676974616c2f7068702d657863657074696f6e732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/hradigital/php-exceptions)[![PHP Version](https://camo.githubusercontent.com/48e97548da9bd1a4aa93c32263e5cd17d06e1d85f37351cb6fafa4a2e94635e2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6872616469676974616c2f7068702d657863657074696f6e732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/hradigital/php-exceptions)[![License](https://camo.githubusercontent.com/d2377152c1245d97e403e70aa64906b4a7fbf6af25e8728b9e1c58d04b246141/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6872616469676974616c2f7068702d657863657074696f6e732e7376673f7374796c653d666c61742d737175617265)](LICENSE)

A curated set of **reusable, semantic domain exceptions** for Domain-Driven Design (DDD) PHP applications.

This package is **framework-agnostic** — zero runtime dependencies beyond the PHP standard library. It was extracted from [`hradigital/php-datatypes`](https://github.com/HRADigital/php-datatypes) so it can evolve independently and be reused across any PHP 8.1+ project.

---

Why this package?
-----------------

[](#why-this-package)

These are **domain exceptions**, not HTTP exceptions. Their names and intent mirror the HTTP 4XX/5XX status families because the vocabulary is widely understood — but they are meant to be raised in the **domain layer**, outside any transport, and translated to a transport-specific representation (HTTP response, RPC error, CLI exit, queue dead-letter) at the boundary.

Throwing the right exception is part of your domain language. Generic `\InvalidArgumentException` or `\RuntimeException` leak plumbing concerns into the domain. This library gives you:

- **Semantic, intent-revealing exception types** organised into Client (caller-fault, 4XX-aligned) and Server (system-fault, 5XX-aligned) families.
- **A common abstract base** (`AbstractBaseException`) that extends `\DomainException` so a single `catch` can capture everything in this package.
- **No framework lock-in** — pure PHP, drop it into any application or framework.

Requirements
------------

[](#requirements)

DependencyVersionPHP`^8.1`Installation
------------

[](#installation)

```
composer require hradigital/php-exceptions
```

Usage
-----

[](#usage)

Every exception in this package extends `AbstractBaseException`, which itself extends PHP's native `\DomainException`. Each subclass ships with a sensible default message and an HTTP-aligned status code (`$code`).

```
use HraDigital\Components\Exceptions\Client\NotFoundException;

throw new NotFoundException('User #42 does not exist.');
```

### Catching by intent

[](#catching-by-intent)

```
use HraDigital\Components\Exceptions\AbstractBaseException;
use HraDigital\Components\Exceptions\Client\ConflictException;
use HraDigital\Components\Exceptions\Client\NotFoundException;
use HraDigital\Components\Exceptions\Client\UnprocessableEntityException;

try {
    $service->updateProfile($payload);
} catch (UnprocessableEntityException $e) {
    // input parsed but failed business-rule validation
} catch (NotFoundException $e) {
    // target aggregate / entity does not exist
} catch (ConflictException $e) {
    // current state of the aggregate refuses this action
} catch (AbstractBaseException $e) {
    // any other domain failure raised by this package
}
```

### Authoring your own exceptions

[](#authoring-your-own-exceptions)

Pick the closest leaf class and extend it — that way callers can still catch by the broader intent.

```
use HraDigital\Components\Exceptions\Client\ConflictException;

class EmailAlreadyTakenException extends ConflictException
{
    protected $message = 'The provided email is already in use.';
}
```

Available exceptions
--------------------

[](#available-exceptions)

Listed in HTTP-status order for orientation. Each class carries a docBlock with its semantic meaning, when to extend it, and (where relevant) the browser behaviour the analogous HTTP status triggers.

**Client — caller-fault (4XX-aligned)**`BadRequestException` (400), `DeniedAccessException` (401), `PaymentRequiredException` (402), `ForbiddenException` (403), `NotFoundException` (404), `MethodNotAllowedException` (405), `NotAcceptableException` (406), `RequestTimeoutException` (408), `ConflictException` (409), `GoneException` (410), `PreconditionFailedException` (412), `UnsupportedMediaTypeException` (415), `RequestedRangeNotSatisfiableException` (416), `ExpectationFailedException` (417), `UnprocessableEntityException` (422), `LockedException` (423), `FailedDependencyException` (424), `TooEarlyException` (425), `PreconditionRequiredException` (428), `TooManyRequestsException` (429), `UnavailableForLegalReasonsException` (451), plus `Request\RequestFailureException` for structured per-field validation failures.

**Server — system-fault (5XX-aligned)**`InternalServerErrorException` (500), `ServerNotImplementedException` (501), `BadGatewayException` (502), `ServerUnavailableException` (503), `GatewayTimeoutException` (504), `InsufficientStorageException` (507), `LoopDetectedException` (508).

Transport-only HTTP statuses (407, 411, 413, 414, 421, 426, 431, 505, 506, 510, 511) are intentionally not represented — they have no platform-agnostic domain meaning.

Testing
-------

[](#testing)

```
composer install
composer test
```

Continuous Integration
----------------------

[](#continuous-integration)

GitHub Actions runs PHPUnit on every push and pull request, across PHP 8.1 / 8.2 / 8.3 / 8.4.

Versioning
----------

[](#versioning)

This package follows [Semantic Versioning 2.0.0](https://semver.org/). Breaking changes only ship in major releases.

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

[](#contributing)

Pull requests are welcome. For substantial changes, please open an issue first to discuss what you'd like to change. Add tests for any new behaviour or bug fix.

Security
--------

[](#security)

If you discover a security vulnerability, please email **** instead of opening a public issue.

License
-------

[](#license)

This package is open-sourced software licensed under the [GNU General Public License v3.0 or later](LICENSE).

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance93

Actively maintained with recent releases

Popularity10

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 87.5% 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

Unknown

Total

1

Last Release

35d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/34803364423357ae62828a472022dc7af10a4b64833418f8b8f4e905f6fa3fc8?d=identicon)[hradigital](/maintainers/hradigital)

---

Top Contributors

[![hugo-azevedo-tg](https://avatars.githubusercontent.com/u/123745232?v=4)](https://github.com/hugo-azevedo-tg "hugo-azevedo-tg (7 commits)")[![HRADigital](https://avatars.githubusercontent.com/u/8511557?v=4)](https://github.com/HRADigital "HRADigital (1 commits)")

---

Tags

phpexceptionsDomain Driven Designddddomaindomain-exceptions

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/hradigital-php-exceptions/health.svg)

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

###  Alternatives

[thejano/laravel-domain-driven-design

Helps to use domain driven design within laravel

15424.8k](/packages/thejano-laravel-domain-driven-design)

PHPackages © 2026

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