decodelabs / exceptional
Better Exceptions for PHP
Installs: 31 311
Dependents: 50
Suggesters: 0
Security: 0
Stars: 3
Watchers: 3
Forks: 0
Open Issues: 0
Requires
- php: ^8.1
- decodelabs/coercion: ^0.2
- decodelabs/glitch-support: ^0.4
- decodelabs/wellspring: ^0.1.0
- symfony/polyfill-mbstring: ^1.7
Requires (Dev)
README
Better Exceptions for PHP
Exceptional aims to offer a radically enhanced Exception framework that decouples the meaning of an Exception from the underlying implementation functionality.
Get news and updates on the DecodeLabs blog.
Installation
Install via Composer:
composer require decodelabs/exceptional
Usage
Exceptional exceptions can be used to greatly simplify how you generate and throw errors in your code, especially if you are writing a shared library.
Pass the name of your intended exception as a static call to the Exceptional base class and have a dynamic exception class created based on the most appropriate PHP Exception class along with a set of related interfaces for easier catching.
use DecodeLabs\Exceptional; // Create OutOfBoundsException throw Exceptional::OutOfBounds('This is out of bounds'); // Implement multiple interfaces throw Exceptional::{'NotFound,BadMethodCall'}( "Didn't find a thing, couldn't call the other thing" ); // You can associate a http code too.. throw Exceptional::CompletelyMadeUpMeaning( message: 'My message', code: 1234, http: 501 ); // Implement already existing Exception interfaces throw Exceptional::{'InvalidArgument,Psr\\Cache\\InvalidArgumentException'}( message: 'Cache items must implement Cache\\IItem', http: 500, data: $item ); // Reference interfaces using a path style throw Exceptional::{'../OtherNamespace/OtherInterface'}('My exception');
Catch an Exceptional exception in the normal way using whichever scope you require:
namespace MyNamespace; try { throw Exceptional::{'NotFound,BadMethodCall'}( "Didn't find a thing, couldn't call the other thing" ); } catch( \Exception | \BadMethodCallException | Exceptional\Exception | Exceptional\NotFoundException | MyNamespace\NotFoundException | MyNamespace\BadMethodCallException ) { // All these types will catch dd($e); }
Traits
Custom functionality can be mixed in to the generated exception automatically by defining traits at the same namespace level as any of the interfaces being implemented.
namespace MyLibrary; trait BadThingExceptionTrait { public function getCustomData(): ?string { return $this->params['customData'] ?? null; } } class Thing { public function doAThing() { throw Exceptional::BadThing( message: 'A bad thing happened', data: [ 'customData' => 'My custom info' ] ); } }