diff --git a/.gitignore b/.gitignore index 37181aa..22ce3e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ .idea -composer.lock -TestReport vendor -.php_cs.cache \ No newline at end of file +.php-cs-fixer.cache diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 2700715..0000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: php - -matrix: - fast_finish: true - include: - - php: 7.1 - - php: 7.2 - - php: 7.3 - -sudo: false - -dist: trusty - -cache: - directories: - - $HOME/.composer/cache - -install: - - composer install - -script: - - composer lint - - composer test \ No newline at end of file diff --git a/Exceptions/Collection/CollectionException.php b/Exceptions/Collection/CollectionException.php index 933c315..c8c1514 100644 --- a/Exceptions/Collection/CollectionException.php +++ b/Exceptions/Collection/CollectionException.php @@ -2,10 +2,9 @@ namespace Exceptions\Collection; -use Exceptions\Helpers\DefaultConstructorTrait; use Exceptions\Helpers\DefaultsInterface; -use Exceptions\Helpers\FromException; -use Exceptions\Helpers\WithContext; +use RuntimeException; +use Throwable; /** * This is a tag like class that is used to regroup all Collection exceptions under a single base class. @@ -13,9 +12,19 @@ * @author Mathieu Dumoulin * @license MIT */ -abstract class CollectionException extends \RuntimeException implements CollectionExceptionInterface, DefaultsInterface +abstract class CollectionException extends RuntimeException implements CollectionExceptionInterface, DefaultsInterface { - use FromException, DefaultConstructorTrait, WithContext; + public function __construct( + string $message = "", + int $code = 0, + null|Throwable $previous = null + ) { + parent::__construct( + message: $message ?: $this->getDefaultMessage(), + code: $code ?: $this->getDefaultCode(), + previous: $previous + ); + } /** * {@inheritdoc} diff --git a/Exceptions/Collection/EmptyException.php b/Exceptions/Collection/EmptyException.php index eaeab3d..cebb117 100644 --- a/Exceptions/Collection/EmptyException.php +++ b/Exceptions/Collection/EmptyException.php @@ -10,6 +10,6 @@ */ class EmptyException extends CollectionException { - const MESSAGE = 'Array/collection is currently empty'; - const CODE = 0; + public const MESSAGE = 'Array/collection is currently empty'; + public const CODE = 0; } diff --git a/Exceptions/Collection/FullException.php b/Exceptions/Collection/FullException.php index e1a2496..bea8476 100644 --- a/Exceptions/Collection/FullException.php +++ b/Exceptions/Collection/FullException.php @@ -4,13 +4,13 @@ /** * Use this exception when an operation on a collection cannot be achieved because the collection has already reached - * it's limit and cannot accept more data. + * its limit and cannot accept more data. * * @author Mathieu Dumoulin * @license MIT */ class FullException extends CollectionException { - const MESSAGE = 'Cannot add items to array/collection, it is already full'; - const CODE = 0; + public const MESSAGE = 'Cannot add items to array/collection, it is already full'; + public const CODE = 0; } diff --git a/Exceptions/Collection/KeyAlreadyExistsException.php b/Exceptions/Collection/KeyAlreadyExistsException.php index ebdcfbc..05ac971 100644 --- a/Exceptions/Collection/KeyAlreadyExistsException.php +++ b/Exceptions/Collection/KeyAlreadyExistsException.php @@ -2,7 +2,7 @@ namespace Exceptions\Collection; -use Exceptions\Tag\ExistsTag; +use Exceptions\Tag\AlreadyExistsTag; /** * Use this exception when an operation on a collection tries to add an element using a key that already exists in the @@ -11,8 +11,8 @@ * @author Mathieu Dumoulin * @license MIT */ -class KeyAlreadyExistsException extends CollectionException implements ExistsTag +class KeyAlreadyExistsException extends CollectionException implements AlreadyExistsTag { - const MESSAGE = 'Key already exists in array/collection'; - const CODE = 0; + public const MESSAGE = 'Key already exists in array/collection'; + public const CODE = 0; } diff --git a/Exceptions/Collection/KeyNotFoundException.php b/Exceptions/Collection/KeyNotFoundException.php index 4f53e01..560bb6e 100644 --- a/Exceptions/Collection/KeyNotFoundException.php +++ b/Exceptions/Collection/KeyNotFoundException.php @@ -17,6 +17,6 @@ */ class KeyNotFoundException extends CollectionException implements NotFoundTag { - const MESSAGE = 'Key not found in array/collection'; - const CODE = 0; + public const MESSAGE = 'Key not found in array/collection'; + public const CODE = 0; } diff --git a/Exceptions/Collection/ReadOnlyArrayException.php b/Exceptions/Collection/ReadOnlyArrayException.php index ef89dfa..79e9433 100644 --- a/Exceptions/Collection/ReadOnlyArrayException.php +++ b/Exceptions/Collection/ReadOnlyArrayException.php @@ -11,6 +11,6 @@ */ class ReadOnlyArrayException extends CollectionException { - const MESSAGE = 'Array/Collection is read-only, you cannot alter it'; - const CODE = 0; + public const MESSAGE = 'Array/Collection is read-only, you cannot alter it'; + public const CODE = 0; } diff --git a/Exceptions/Collection/ReadOnlyArrayItemException.php b/Exceptions/Collection/ReadOnlyArrayItemException.php index 8e85ac6..1becfbb 100644 --- a/Exceptions/Collection/ReadOnlyArrayItemException.php +++ b/Exceptions/Collection/ReadOnlyArrayItemException.php @@ -11,6 +11,6 @@ */ class ReadOnlyArrayItemException extends CollectionException { - const MESSAGE = 'Array/Collection item is read-only, you cannot modify it'; - const CODE = 0; + public const MESSAGE = 'Array/Collection item is read-only, you cannot modify it'; + public const CODE = 0; } diff --git a/Exceptions/Data/DataException.php b/Exceptions/Data/DataException.php index 234f984..3701fad 100644 --- a/Exceptions/Data/DataException.php +++ b/Exceptions/Data/DataException.php @@ -2,10 +2,9 @@ namespace Exceptions\Data; -use Exceptions\Helpers\DefaultConstructorTrait; use Exceptions\Helpers\DefaultsInterface; -use Exceptions\Helpers\FromException; -use Exceptions\Helpers\WithContext; +use RuntimeException; +use Throwable; /** * This is a tag like class that is used to regroup all Data exceptions under a single base class. @@ -13,9 +12,19 @@ * @author Mathieu Dumoulin * @license MIT */ -abstract class DataException extends \RuntimeException implements DataExceptionInterface, DefaultsInterface +abstract class DataException extends RuntimeException implements DataExceptionInterface, DefaultsInterface { - use FromException, DefaultConstructorTrait, WithContext; + public function __construct( + string $message = "", + int $code = 0, + null|Throwable $previous = null + ) { + parent::__construct( + message: $message ?: $this->getDefaultMessage(), + code: $code ?: $this->getDefaultCode(), + previous: $previous + ); + } /** * {@inheritdoc} diff --git a/Exceptions/Data/FormatException.php b/Exceptions/Data/FormatException.php index 2b601fe..974b99f 100644 --- a/Exceptions/Data/FormatException.php +++ b/Exceptions/Data/FormatException.php @@ -15,6 +15,6 @@ */ class FormatException extends DataException implements InvalidDataTag { - const MESSAGE = 'Data provided is not of the expected format or cannot be parsed correctly.'; - const CODE = 0; + public const MESSAGE = 'Data provided is not of the expected format or cannot be parsed correctly.'; + public const CODE = 0; } diff --git a/Exceptions/Data/FoundTooLittleException.php b/Exceptions/Data/FoundTooLittleException.php index a2f7362..3897f27 100644 --- a/Exceptions/Data/FoundTooLittleException.php +++ b/Exceptions/Data/FoundTooLittleException.php @@ -3,8 +3,8 @@ namespace Exceptions\Data; /** - * Use this exception when the data requested by your code was found but it found actually less than expected. A - * good use for this is when you are looking for a specific set of items such as 10 items but you end up finding only + * Use this exception when the data requested by your code was found, but it found actually less than expected. A + * good use for this is when you are looking for a specific set of items such as 10 items, but you end up finding only * 9. In this case, you throw this exception. * * If the code in context is a service provider that queries a database, this would be the right exception to throw @@ -16,6 +16,6 @@ */ class FoundTooLittleException extends DataException { - const MESSAGE = 'Found too little items in the data source.'; - const CODE = 0; + public const MESSAGE = 'Found too little items in the data source.'; + public const CODE = 0; } diff --git a/Exceptions/Data/FoundTooManyException.php b/Exceptions/Data/FoundTooManyException.php index 0f35029..bec8391 100644 --- a/Exceptions/Data/FoundTooManyException.php +++ b/Exceptions/Data/FoundTooManyException.php @@ -3,7 +3,7 @@ namespace Exceptions\Data; /** - * Use this exception when the data requested by your code was found and it found actually more than expected. A good + * Use this exception when the data requested by your code was found, and it found actually more than expected. A good * use for this is the findSingle usual function we find in many library and orm. If you have more than 1 record * found, it might mean that you should send back this exception. * @@ -16,6 +16,6 @@ */ class FoundTooManyException extends DataException { - const MESSAGE = 'Found too many items in the data source.'; - const CODE = 0; + public const MESSAGE = 'Found too many items in the data source.'; + public const CODE = 0; } diff --git a/Exceptions/Data/IntegrityException.php b/Exceptions/Data/IntegrityException.php index 130be0e..b23638b 100644 --- a/Exceptions/Data/IntegrityException.php +++ b/Exceptions/Data/IntegrityException.php @@ -13,6 +13,6 @@ */ class IntegrityException extends DataException implements InvalidDataTag { - const MESSAGE = 'Data provided is not of the expected format or cannot be parsed correctly.'; - const CODE = 0; + public const MESSAGE = 'Data provided is not of the expected format or cannot be parsed correctly.'; + public const CODE = 0; } diff --git a/Exceptions/Data/NotFoundException.php b/Exceptions/Data/NotFoundException.php index cd7e533..5f3831c 100644 --- a/Exceptions/Data/NotFoundException.php +++ b/Exceptions/Data/NotFoundException.php @@ -18,6 +18,6 @@ */ class NotFoundException extends DataException implements NotFoundTag { - const MESSAGE = 'Data requested for cannot be found in the data source.'; - const CODE = 0; + public const MESSAGE = 'Data requested for cannot be found in the data source.'; + public const CODE = 0; } diff --git a/Exceptions/Data/TypeException.php b/Exceptions/Data/TypeException.php index 4e89261..47d1c04 100644 --- a/Exceptions/Data/TypeException.php +++ b/Exceptions/Data/TypeException.php @@ -14,6 +14,6 @@ */ class TypeException extends DataException implements InvalidDataTag { - const MESSAGE = 'Type of the data is incorrect'; - const CODE = 0; + public const MESSAGE = 'Type of the data is incorrect'; + public const CODE = 0; } diff --git a/Exceptions/Data/ValidationException.php b/Exceptions/Data/ValidationException.php index 67fe573..011694b 100644 --- a/Exceptions/Data/ValidationException.php +++ b/Exceptions/Data/ValidationException.php @@ -18,6 +18,6 @@ */ class ValidationException extends DataException implements InvalidDataTag { - const MESSAGE = 'Provided data does not conform to business model or basic domain validation rules'; - const CODE = 0; + public const MESSAGE = 'Provided data does not conform to business model or basic domain validation rules'; + public const CODE = 0; } diff --git a/Exceptions/Http/Client/BadRequestException.php b/Exceptions/Http/Client/BadRequestException.php index ba16bac..8b233fc 100644 --- a/Exceptions/Http/Client/BadRequestException.php +++ b/Exceptions/Http/Client/BadRequestException.php @@ -19,10 +19,10 @@ class BadRequestException extends ClientErrorException implements InvalidDataTag /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 400; + public const HTTP_CODE = 400; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Bad Request: The request could not be understood by the server due to malformed syntax. The client should not repeat the request without modifications.'; + public const HTTP_MESSAGE = 'Bad Request: The request could not be understood by the server due to malformed syntax. The client should not repeat the request without modifications.'; } diff --git a/Exceptions/Http/Client/ClientErrorException.php b/Exceptions/Http/Client/ClientErrorException.php index c775467..22fae14 100644 --- a/Exceptions/Http/Client/ClientErrorException.php +++ b/Exceptions/Http/Client/ClientErrorException.php @@ -3,7 +3,6 @@ namespace Exceptions\Http\Client; use Exceptions\Http\HttpException; -use Exceptions\Tag\AbortedTag; /** * This is a tag like class that is used to regroup all Http/Client exceptions under a single base class. @@ -11,12 +10,12 @@ * Never throw an exception at the user, always catch it can synthesize it to a correct html response with * appropriate headers. You can use the constants and accessor to get HTML values to return. */ -abstract class ClientErrorException extends HttpException implements ClientErrorExceptionInterface, AbortedTag +abstract class ClientErrorException extends HttpException implements ClientErrorExceptionInterface { /** * {@inheritdoc} */ - public static function getHttpCodeClass() + public static function getHttpCodeClass(): int { return self::CODE_CLASS_CLIENT_ERROR; } diff --git a/Exceptions/Http/Client/ConflictException.php b/Exceptions/Http/Client/ConflictException.php index 0a1629c..f217e61 100644 --- a/Exceptions/Http/Client/ConflictException.php +++ b/Exceptions/Http/Client/ConflictException.php @@ -18,10 +18,10 @@ class ConflictException extends ClientErrorException implements InvalidDataTag /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 409; + public const HTTP_CODE = 409; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Conflict: The request could not be completed due to a conflict with the current state of the resource. Fix the errors that are producing the conflict and then try again. This error is often caused by desynchronized states between client and server, something changed on one or the other and the resources are out of sync.'; + public const HTTP_MESSAGE = 'Conflict: The request could not be completed due to a conflict with the current state of the resource. Fix the errors that are producing the conflict and then try again. This error is often caused by desynchronized states between client and server, something changed on one or the other and the resources are out of sync.'; } diff --git a/Exceptions/Http/Client/ExpectationFailedException.php b/Exceptions/Http/Client/ExpectationFailedException.php index 4aef4a4..23dec86 100644 --- a/Exceptions/Http/Client/ExpectationFailedException.php +++ b/Exceptions/Http/Client/ExpectationFailedException.php @@ -5,7 +5,7 @@ use Exceptions\Tag\InvalidDataTag; /** - * The request could not be completed because the request specified a "Expect" request header that the server cannot + * The request could not be completed because the request specified an "Expect" request header that the server cannot * fulfill. * * Never throw an exception at the user, always catch it can synthesize it to a correct html response with @@ -19,10 +19,10 @@ class ExpectationFailedException extends ClientErrorException implements Invalid /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 417; + public const HTTP_CODE = 417; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Expectation Failed: The request cannot be completed because the request you are making contains an Expect header that the server cannot fulfill.'; + public const HTTP_MESSAGE = 'Expectation Failed: The request cannot be completed because the request you are making contains an Expect header that the server cannot fulfill.'; } diff --git a/Exceptions/Http/Client/FailedDependencyException.php b/Exceptions/Http/Client/FailedDependencyException.php index d5b8b1f..dd84af7 100644 --- a/Exceptions/Http/Client/FailedDependencyException.php +++ b/Exceptions/Http/Client/FailedDependencyException.php @@ -18,10 +18,10 @@ class FailedDependencyException extends ClientErrorException /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 424; + public const HTTP_CODE = 424; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Failed Dependency: The request cannot be completed because an underlying process failed to complete properly or there is a dependency that cannot be met around the process.'; + public const HTTP_MESSAGE = 'Failed Dependency: The request cannot be completed because an underlying process failed to complete properly or there is a dependency that cannot be met around the process.'; } diff --git a/Exceptions/Http/Client/ForbiddenException.php b/Exceptions/Http/Client/ForbiddenException.php index 0e90c26..2c1ff5a 100644 --- a/Exceptions/Http/Client/ForbiddenException.php +++ b/Exceptions/Http/Client/ForbiddenException.php @@ -19,10 +19,10 @@ class ForbiddenException extends ClientErrorException implements ForbiddenTag /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 403; + public const HTTP_CODE = 403; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Forbidden: The server understood the request, but is refusing to fulfill it. Authorization will not help and the request should not be repeated.'; + public const HTTP_MESSAGE = 'Forbidden: The server understood the request, but is refusing to fulfill it. Authorization will not help and the request should not be repeated.'; } diff --git a/Exceptions/Http/Client/GoneException.php b/Exceptions/Http/Client/GoneException.php index fdeb507..cad206d 100644 --- a/Exceptions/Http/Client/GoneException.php +++ b/Exceptions/Http/Client/GoneException.php @@ -21,10 +21,10 @@ class GoneException extends ClientErrorException implements NotFoundTag /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 410; + public const HTTP_CODE = 410; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Gone: The request cannot be completed because the resource you are requesting has been moved or has changed state.'; + public const HTTP_MESSAGE = 'Gone: The request cannot be completed because the resource you are requesting has been moved or has changed state.'; } diff --git a/Exceptions/Http/Client/ImATeapotException.php b/Exceptions/Http/Client/ImATeapotException.php deleted file mode 100644 index 46a1d1d..0000000 --- a/Exceptions/Http/Client/ImATeapotException.php +++ /dev/null @@ -1,28 +0,0 @@ - - * @license MIT - */ -class ImATeapotException extends ClientErrorException -{ - /** - * Returns the HTTP error code for that exception. - */ - const HTTP_CODE = 418; - - /** - * Returns the HTTP error message for that exception. - */ - const HTTP_MESSAGE = 'I\'m a teapot: Why are you asking me to do this?'; -} diff --git a/Exceptions/Http/Client/LengthRequiredException.php b/Exceptions/Http/Client/LengthRequiredException.php index c794050..5dbfdf0 100644 --- a/Exceptions/Http/Client/LengthRequiredException.php +++ b/Exceptions/Http/Client/LengthRequiredException.php @@ -19,10 +19,10 @@ class LengthRequiredException extends ClientErrorException implements InvalidDat /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 411; + public const HTTP_CODE = 411; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Length Required: The request cannot be completed because the resource you are requesting for can only be satisfied if you provide the length of the request\'s payload/body.'; + public const HTTP_MESSAGE = 'Length Required: The request cannot be completed because the resource you are requesting for can only be satisfied if you provide the length of the request\'s payload/body.'; } diff --git a/Exceptions/Http/Client/LockedException.php b/Exceptions/Http/Client/LockedException.php index 70d352c..99d1a08 100644 --- a/Exceptions/Http/Client/LockedException.php +++ b/Exceptions/Http/Client/LockedException.php @@ -19,10 +19,10 @@ class LockedException extends ClientErrorException implements ForbiddenTag /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 423; + public const HTTP_CODE = 423; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Locked: The request cannot be completed because the resource you are trying to access is locked by another process.'; + public const HTTP_MESSAGE = 'Locked: The request cannot be completed because the resource you are trying to access is locked by another process.'; } diff --git a/Exceptions/Http/Client/MethodNotAllowedException.php b/Exceptions/Http/Client/MethodNotAllowedException.php index 26f053d..376c3c6 100644 --- a/Exceptions/Http/Client/MethodNotAllowedException.php +++ b/Exceptions/Http/Client/MethodNotAllowedException.php @@ -18,10 +18,10 @@ class MethodNotAllowedException extends ClientErrorException implements InvalidD /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 405; + public const HTTP_CODE = 405; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Method Not Allowed: The method specified in the request is not allowed for the requested resource. The resource was found and is accessible, but cannot be accessed using this method.'; + public const HTTP_MESSAGE = 'Method Not Allowed: The method specified in the request is not allowed for the requested resource. The resource was found and is accessible, but cannot be accessed using this method.'; } diff --git a/Exceptions/Http/Client/MisdirectedRequestException.php b/Exceptions/Http/Client/MisdirectedRequestException.php index 1b50f33..b231243 100644 --- a/Exceptions/Http/Client/MisdirectedRequestException.php +++ b/Exceptions/Http/Client/MisdirectedRequestException.php @@ -17,10 +17,10 @@ class MisdirectedRequestException extends ClientErrorException /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 421; + public const HTTP_CODE = 421; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Misdirected Request: The server cannot respond to this request due to a lack of resources or features. Please direct this request to the proper server instead.'; + public const HTTP_MESSAGE = 'Misdirected Request: The server cannot respond to this request due to a lack of resources or features. Please direct this request to the proper server instead.'; } diff --git a/Exceptions/Http/Client/NotAcceptableException.php b/Exceptions/Http/Client/NotAcceptableException.php index a2680c5..8973569 100644 --- a/Exceptions/Http/Client/NotAcceptableException.php +++ b/Exceptions/Http/Client/NotAcceptableException.php @@ -19,10 +19,10 @@ class NotAcceptableException extends ClientErrorException implements InvalidData /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 406; + public const HTTP_CODE = 406; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Not Acceptable: The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request.'; + public const HTTP_MESSAGE = 'Not Acceptable: The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request.'; } diff --git a/Exceptions/Http/Client/NotFoundException.php b/Exceptions/Http/Client/NotFoundException.php index cad1a4a..28cc719 100644 --- a/Exceptions/Http/Client/NotFoundException.php +++ b/Exceptions/Http/Client/NotFoundException.php @@ -18,10 +18,10 @@ class NotFoundException extends ClientErrorException implements NotFoundTag /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 404; + public const HTTP_CODE = 404; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Not found: The requested entity cannot be found, this may be returned because entity is not accessible using requested credentials, because of a recent state change or because entity cannot be found at all.'; + public const HTTP_MESSAGE = 'Not found: The requested entity cannot be found, this may be returned because entity is not accessible using requested credentials, because of a recent state change or because entity cannot be found at all.'; } diff --git a/Exceptions/Http/Client/PayloadTooLargeException.php b/Exceptions/Http/Client/PayloadTooLargeException.php index 36efd1a..6892e44 100644 --- a/Exceptions/Http/Client/PayloadTooLargeException.php +++ b/Exceptions/Http/Client/PayloadTooLargeException.php @@ -12,10 +12,15 @@ * @author Mathieu Dumoulin * @license MIT */ -class PayloadTooLargeException extends RequestEntityTooLargeException +class PayloadTooLargeException { + /** + * Returns the HTTP error code for that exception. + */ + public const HTTP_CODE = 413; + /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Payload Too Large: The server is refusing to process a request because the payload is larger than the server is willing or able to process.'; + public const HTTP_MESSAGE = 'Payload Too Large: The server is refusing to process a request because the payload is larger than the server is willing or able to process.'; } diff --git a/Exceptions/Http/Client/PaymentRequiredException.php b/Exceptions/Http/Client/PaymentRequiredException.php index b4dba3d..74e89fc 100644 --- a/Exceptions/Http/Client/PaymentRequiredException.php +++ b/Exceptions/Http/Client/PaymentRequiredException.php @@ -5,7 +5,7 @@ use Exceptions\Tag\ForbiddenTag; /** - * The request requires user to pay to access the resource or he must supply different identification or credentials + * The request requires user to pay to access the resource, or he must supply different identification or credentials * to gain access to the resource. * * Never throw an exception at the user, always catch it can synthesize it to a correct html response with @@ -19,10 +19,10 @@ class PaymentRequiredException extends ClientErrorException implements Forbidden /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 402; + public const HTTP_CODE = 402; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Payment Required: The resource you are accessing is not available based on your current permission but could be if you paid and extra fee. This can be related to plan limitations or just pay to use content.'; + public const HTTP_MESSAGE = 'Payment Required: The resource you are accessing is not available based on your current permission but could be if you paid and extra fee. This can be related to plan limitations or just pay to use content.'; } diff --git a/Exceptions/Http/Client/PreConditionFailedException.php b/Exceptions/Http/Client/PreConditionFailedException.php index b605525..dfd4e1d 100644 --- a/Exceptions/Http/Client/PreConditionFailedException.php +++ b/Exceptions/Http/Client/PreConditionFailedException.php @@ -18,10 +18,10 @@ class PreConditionFailedException extends ClientErrorException implements Invali /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 412; + public const HTTP_CODE = 412; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Pre-condition Failed: The request cannot be completed because the server cannot provide content based on the pre-conditions you set.'; + public const HTTP_MESSAGE = 'Pre-condition Failed: The request cannot be completed because the server cannot provide content based on the pre-conditions you set.'; } diff --git a/Exceptions/Http/Client/PreConditionRequiredException.php b/Exceptions/Http/Client/PreConditionRequiredException.php index 0e5cd9a..5c4c50c 100644 --- a/Exceptions/Http/Client/PreConditionRequiredException.php +++ b/Exceptions/Http/Client/PreConditionRequiredException.php @@ -18,10 +18,10 @@ class PreConditionRequiredException extends ClientErrorException implements Inva /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 428; + public const HTTP_CODE = 428; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Pre-condition Required: The request cannot be completed because the request was not made using an a pre-condition header that should have been included with it.'; + public const HTTP_MESSAGE = 'Pre-condition Required: The request cannot be completed because the request was not made using an a pre-condition header that should have been included with it.'; } diff --git a/Exceptions/Http/Client/ProxyAuthorizationRequiredException.php b/Exceptions/Http/Client/ProxyAuthorizationRequiredException.php index 3b11485..73973f0 100644 --- a/Exceptions/Http/Client/ProxyAuthorizationRequiredException.php +++ b/Exceptions/Http/Client/ProxyAuthorizationRequiredException.php @@ -18,10 +18,10 @@ class ProxyAuthorizationRequiredException extends ClientErrorException implement /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 407; + public const HTTP_CODE = 407; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Proxy Authorization Required: The request you made tried to pass through a proxy that is refusing your credentials or refusing your anonymity. Please re-issue the request with proper credentials.'; + public const HTTP_MESSAGE = 'Proxy Authorization Required: The request you made tried to pass through a proxy that is refusing your credentials or refusing your anonymity. Please re-issue the request with proper credentials.'; } diff --git a/Exceptions/Http/Client/RangeNotSatisfiableException.php b/Exceptions/Http/Client/RangeNotSatisfiableException.php index cd4bfc6..01de877 100644 --- a/Exceptions/Http/Client/RangeNotSatisfiableException.php +++ b/Exceptions/Http/Client/RangeNotSatisfiableException.php @@ -12,6 +12,15 @@ * @author Mathieu Dumoulin * @license MIT */ -class RangeNotSatisfiableException extends RequestedRangeNotSatisfiableException +class RangeNotSatisfiableException { + /** + * Returns the HTTP error code for that exception. + */ + public const HTTP_CODE = 416; + + /** + * Returns the HTTP error message for that exception. + */ + public const HTTP_MESSAGE = 'Range Not Satisfiable: The server is refusing to process a request because the requested length/range cannot be satisfied due to missing data.'; } diff --git a/Exceptions/Http/Client/RequestEntityTooLargeException.php b/Exceptions/Http/Client/RequestEntityTooLargeException.php deleted file mode 100644 index b59808c..0000000 --- a/Exceptions/Http/Client/RequestEntityTooLargeException.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @license MIT - */ -class RequestEntityTooLargeException extends ClientErrorException implements InvalidDataTag -{ - /** - * Returns the HTTP error code for that exception. - */ - const HTTP_CODE = 413; - - /** - * Returns the HTTP error message for that exception. - */ - const HTTP_MESSAGE = 'Request Entity Too Large: The server is refusing to process a request because the message is larger than the server is willing or able to process.'; -} diff --git a/Exceptions/Http/Client/RequestHeaderFieldsTooLargeException.php b/Exceptions/Http/Client/RequestHeaderFieldsTooLargeException.php index 91e1de7..2d75f84 100644 --- a/Exceptions/Http/Client/RequestHeaderFieldsTooLargeException.php +++ b/Exceptions/Http/Client/RequestHeaderFieldsTooLargeException.php @@ -20,10 +20,10 @@ class RequestHeaderFieldsTooLargeException extends ClientErrorException implemen /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 431; + public const HTTP_CODE = 431; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Request Header Fields Too Large: The request contained too much data in the header fields or one specific field contained too much data in it.'; + public const HTTP_MESSAGE = 'Request Header Fields Too Large: The request contained too much data in the header fields or one specific field contained too much data in it.'; } diff --git a/Exceptions/Http/Client/RequestTimeoutException.php b/Exceptions/Http/Client/RequestTimeoutException.php index 3b10be8..48fdde0 100644 --- a/Exceptions/Http/Client/RequestTimeoutException.php +++ b/Exceptions/Http/Client/RequestTimeoutException.php @@ -16,10 +16,10 @@ class RequestTimeoutException extends ClientErrorException /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 408; + public const HTTP_CODE = 408; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Request Timeout: A process further down the request chain failed to respond in time. You can try again but you might get the same response if the server load or the problem persists downstream.'; + public const HTTP_MESSAGE = 'Request Timeout: A process further down the request chain failed to respond in time. You can try again but you might get the same response if the server load or the problem persists downstream.'; } diff --git a/Exceptions/Http/Client/RequestedRangeNotSatisfiableException.php b/Exceptions/Http/Client/RequestedRangeNotSatisfiableException.php deleted file mode 100644 index f832e53..0000000 --- a/Exceptions/Http/Client/RequestedRangeNotSatisfiableException.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @license MIT - */ -class RequestedRangeNotSatisfiableException extends ClientErrorException implements InvalidDataTag -{ - /** - * Returns the HTTP error code for that exception. - */ - const HTTP_CODE = 416; - - /** - * Returns the HTTP error message for that exception. - */ - const HTTP_MESSAGE = 'Range Not Satisfiable: The server is refusing to process a request because the requested length/range cannot be satisfied due to missing data.'; -} diff --git a/Exceptions/Http/Client/TooManyRequestsException.php b/Exceptions/Http/Client/TooManyRequestsException.php index 35ee8ab..496934c 100644 --- a/Exceptions/Http/Client/TooManyRequestsException.php +++ b/Exceptions/Http/Client/TooManyRequestsException.php @@ -19,10 +19,10 @@ class TooManyRequestsException extends ClientErrorException implements Forbidden /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 429; - + public const HTTP_CODE = 429; + /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Too Many Requests: The request you are making cannot be completed because you are making too many requests to this system. Please try again later.'; + public const HTTP_MESSAGE = 'Too Many Requests: The request you are making cannot be completed because you are making too many requests to this system. Please try again later.'; } diff --git a/Exceptions/Http/Client/URITooLongException.php b/Exceptions/Http/Client/URITooLongException.php index e40447c..0d37981 100644 --- a/Exceptions/Http/Client/URITooLongException.php +++ b/Exceptions/Http/Client/URITooLongException.php @@ -6,7 +6,7 @@ /** * The server will not provide a response because the request URI you send was too long and might be missing important - * information. Instead the server refuses the server it in case he might misunderstand it. + * information. Instead, the server refuses the server it in case he might misunderstand it. * * Never throw an exception at the user, always catch it can synthesize it to a correct html response with * appropriate headers. You can use the constants and accessor to get HTML values to return. @@ -19,10 +19,10 @@ class URITooLongException extends ClientErrorException implements InvalidDataTag /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 414; + public const HTTP_CODE = 414; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'URI Too Long: The server is refusing to process a request because the requested URI was too long and response might not be accurate.'; + public const HTTP_MESSAGE = 'URI Too Long: The server is refusing to process a request because the requested URI was too long and response might not be accurate.'; } diff --git a/Exceptions/Http/Client/UnauthorizedException.php b/Exceptions/Http/Client/UnauthorizedException.php index 516c3c9..7b82541 100644 --- a/Exceptions/Http/Client/UnauthorizedException.php +++ b/Exceptions/Http/Client/UnauthorizedException.php @@ -20,10 +20,10 @@ class UnauthorizedException extends ClientErrorException implements Unauthorized /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 401; + public const HTTP_CODE = 401; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Unauthorized: The request requires user authentication.'; + public const HTTP_MESSAGE = 'Unauthorized: The request requires user authentication.'; } diff --git a/Exceptions/Http/Client/UnavailableForLegalReasonsException.php b/Exceptions/Http/Client/UnavailableForLegalReasonsException.php index 753297a..61a1977 100644 --- a/Exceptions/Http/Client/UnavailableForLegalReasonsException.php +++ b/Exceptions/Http/Client/UnavailableForLegalReasonsException.php @@ -6,7 +6,7 @@ /** * The request could not be satisfied because a legal restriction was made on that resource. This should be mostly - * used against resources that have been blocked for a legal demand but you can use it for anything that would cause + * used against resources that have been blocked for a legal demand, but you can use it for anything that would cause * legal infringement. * * Never throw an exception at the user, always catch it can synthesize it to a correct html response with @@ -20,10 +20,10 @@ class UnavailableForLegalReasonsException extends ClientErrorException implement /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 451; + public const HTTP_CODE = 451; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Unavailable For Legal Reasons: The request cannot be fulfilled because it would act on a resource that is legally restricted or would cause a legal infringement.'; + public const HTTP_MESSAGE = 'Unavailable For Legal Reasons: The request cannot be fulfilled because it would act on a resource that is legally restricted or would cause a legal infringement.'; } diff --git a/Exceptions/Http/Client/UnprocessableEntityException.php b/Exceptions/Http/Client/UnprocessableEntityException.php index b8be6da..85f148d 100644 --- a/Exceptions/Http/Client/UnprocessableEntityException.php +++ b/Exceptions/Http/Client/UnprocessableEntityException.php @@ -18,10 +18,10 @@ class UnprocessableEntityException extends ClientErrorException implements Inval /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 422; + public const HTTP_CODE = 422; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors, validation errors or domain constraints such as uniqueness of values.'; + public const HTTP_MESSAGE = 'Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors, validation errors or domain constraints such as uniqueness of values.'; } diff --git a/Exceptions/Http/Client/UnrecoverableErrorException.php b/Exceptions/Http/Client/UnrecoverableErrorException.php index c250b78..da9cc85 100644 --- a/Exceptions/Http/Client/UnrecoverableErrorException.php +++ b/Exceptions/Http/Client/UnrecoverableErrorException.php @@ -2,8 +2,6 @@ namespace Exceptions\Http\Client; -use Exceptions\Tag\AbortedTag; - /** * The server encountered an unrecoverable error with an internal provider while processing the request * @@ -13,15 +11,15 @@ * @author Jean-Christophe Binet * @license MIT */ -class UnrecoverableErrorException extends ClientErrorException implements AbortedTag +class UnrecoverableErrorException extends ClientErrorException { /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 456; + public const HTTP_CODE = 456; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'The request cannot be fulfilled due to an unrecoverable error with an internal provider'; + public const HTTP_MESSAGE = 'The request cannot be fulfilled due to an unrecoverable error with an internal provider'; } diff --git a/Exceptions/Http/Client/UnsupportedMediaTypeException.php b/Exceptions/Http/Client/UnsupportedMediaTypeException.php index 450c8c0..aa657cc 100644 --- a/Exceptions/Http/Client/UnsupportedMediaTypeException.php +++ b/Exceptions/Http/Client/UnsupportedMediaTypeException.php @@ -18,10 +18,10 @@ class UnsupportedMediaTypeException extends ClientErrorException implements Inva /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 415; + public const HTTP_CODE = 415; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Unsupported Media Type: The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method.'; + public const HTTP_MESSAGE = 'Unsupported Media Type: The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method.'; } diff --git a/Exceptions/Http/Client/UpgradeRequiredException.php b/Exceptions/Http/Client/UpgradeRequiredException.php index ef93a74..72f78b7 100644 --- a/Exceptions/Http/Client/UpgradeRequiredException.php +++ b/Exceptions/Http/Client/UpgradeRequiredException.php @@ -21,10 +21,10 @@ class UpgradeRequiredException extends ClientErrorException implements InvalidDa /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 426; + public const HTTP_CODE = 426; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Upgrade Required: The request cannot be completed because the request was made using an outdated technology or an outdated message structure.'; + public const HTTP_MESSAGE = 'Upgrade Required: The request cannot be completed because the request was made using an outdated technology or an outdated message structure.'; } diff --git a/Exceptions/Http/HttpException.php b/Exceptions/Http/HttpException.php index 1499d57..d904d28 100644 --- a/Exceptions/Http/HttpException.php +++ b/Exceptions/Http/HttpException.php @@ -2,10 +2,9 @@ namespace Exceptions\Http; -use Exceptions\Helpers\DefaultConstructorTrait; use Exceptions\Helpers\DefaultsInterface; -use Exceptions\Helpers\FromException; -use Exceptions\Helpers\WithContext; +use RuntimeException; +use Throwable; /** * This is a tag like class that is used to regroup all Http exceptions under a single base class. @@ -16,9 +15,19 @@ * @author Mathieu Dumoulin * @license MIT */ -abstract class HttpException extends \RuntimeException implements HttpExceptionInterface, DefaultsInterface +abstract class HttpException extends RuntimeException implements HttpExceptionInterface, DefaultsInterface { - use FromException, DefaultConstructorTrait, WithContext; + public function __construct( + string $message = "", + int $code = 0, + null|Throwable $previous = null + ) { + parent::__construct( + message: $message ?: $this->getDefaultMessage(), + code: $code ?: $this->getDefaultCode(), + previous: $previous + ); + } /** * {@inheritdoc} @@ -39,7 +48,7 @@ public static function getDefaultCode(): int /** * {@inheritdoc} */ - public static function getHttpCode() + public static function getHttpCode(): int { return static::HTTP_CODE; } @@ -47,7 +56,7 @@ public static function getHttpCode() /** * {@inheritdoc} */ - public static function getHttpMessage() + public static function getHttpMessage(): string { return static::HTTP_MESSAGE; } diff --git a/Exceptions/Http/HttpExceptionInterface.php b/Exceptions/Http/HttpExceptionInterface.php index 8047e0e..cb424ef 100644 --- a/Exceptions/Http/HttpExceptionInterface.php +++ b/Exceptions/Http/HttpExceptionInterface.php @@ -13,31 +13,31 @@ interface HttpExceptionInterface /** * Represents client errors. */ - const CODE_CLASS_CLIENT_ERROR = 400; + public const CODE_CLASS_CLIENT_ERROR = 400; /** * Represents server errors. */ - const CODE_CLASS_SERVER_ERROR = 500; + public const CODE_CLASS_SERVER_ERROR = 500; /** * Returns the standard HTTP code class associated with this exception. * * @return int */ - public static function getHttpCodeClass(); + public static function getHttpCodeClass(): int; /** * Returns the standard HTTP code associated with this exception. * * @return int */ - public static function getHttpCode(); + public static function getHttpCode(): int; /** * Returns the standard HTTP message associated with this exception. * * @return string */ - public static function getHttpMessage(); + public static function getHttpMessage(): string; } diff --git a/Exceptions/Http/Server/BadGatewayException.php b/Exceptions/Http/Server/BadGatewayException.php index f43fd3e..71c66ea 100644 --- a/Exceptions/Http/Server/BadGatewayException.php +++ b/Exceptions/Http/Server/BadGatewayException.php @@ -16,10 +16,10 @@ class BadGatewayException extends ServerErrorException /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 502; + public const HTTP_CODE = 502; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Bad Gateway: The server cannot complete the request because a downstream process failed to respond properly.'; + public const HTTP_MESSAGE = 'Bad Gateway: The server cannot complete the request because a downstream process failed to respond properly.'; } diff --git a/Exceptions/Http/Server/GatewayTimeoutException.php b/Exceptions/Http/Server/GatewayTimeoutException.php index 72bbf7a..f294ceb 100644 --- a/Exceptions/Http/Server/GatewayTimeoutException.php +++ b/Exceptions/Http/Server/GatewayTimeoutException.php @@ -17,10 +17,10 @@ class GatewayTimeoutException extends ServerErrorException /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 504; + public const HTTP_CODE = 504; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Gateway Timeout: This server is acting as a gateway or proxy to another server but the underlying server or process failed to respond in time.'; + public const HTTP_MESSAGE = 'Gateway Timeout: This server is acting as a gateway or proxy to another server but the underlying server or process failed to respond in time.'; } diff --git a/Exceptions/Http/Server/HttpVersionNotSupportedException.php b/Exceptions/Http/Server/HttpVersionNotSupportedException.php index f46d2bd..67c3667 100644 --- a/Exceptions/Http/Server/HttpVersionNotSupportedException.php +++ b/Exceptions/Http/Server/HttpVersionNotSupportedException.php @@ -16,10 +16,10 @@ class HttpVersionNotSupportedException extends ServerErrorException /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 505; + public const HTTP_CODE = 505; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'HTTP Version Not Supported: This server cannot understand the request using the HTTP protocol version you are using.'; + public const HTTP_MESSAGE = 'HTTP Version Not Supported: This server cannot understand the request using the HTTP protocol version you are using.'; } diff --git a/Exceptions/Http/Server/InsuficientStorageException.php b/Exceptions/Http/Server/InsufficientStorageException.php similarity index 64% rename from Exceptions/Http/Server/InsuficientStorageException.php rename to Exceptions/Http/Server/InsufficientStorageException.php index 8a0e8b8..983f222 100644 --- a/Exceptions/Http/Server/InsuficientStorageException.php +++ b/Exceptions/Http/Server/InsufficientStorageException.php @@ -13,15 +13,15 @@ * @author Mathieu Dumoulin * @license MIT */ -class InsuficientStorageException extends ServerErrorException +class InsufficientStorageException extends ServerErrorException { /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 507; + public const HTTP_CODE = 507; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Insuficient Storage: This server cannot process the request because it would/has run out of space while producing the response. Alternatively, this could also mean the server ran out of disk space or that your request has limited resources and that makes the request impossible to fulfill.'; + public const HTTP_MESSAGE = 'Insufficient Storage: This server cannot process the request because it would/has run out of space while producing the response. Alternatively, this could also mean the server ran out of disk space or that your request has limited resources and that makes the request impossible to fulfill.'; } diff --git a/Exceptions/Http/Server/InternalServerErrorException.php b/Exceptions/Http/Server/InternalServerErrorException.php index 7fab480..fec0698 100644 --- a/Exceptions/Http/Server/InternalServerErrorException.php +++ b/Exceptions/Http/Server/InternalServerErrorException.php @@ -16,10 +16,10 @@ class InternalServerErrorException extends ServerErrorException /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 500; + public const HTTP_CODE = 500; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Internal Server Error: The server encountered an unexpected condition which prevented it from fulfilling the request.'; + public const HTTP_MESSAGE = 'Internal Server Error: The server encountered an unexpected condition which prevented it from fulfilling the request.'; } diff --git a/Exceptions/Http/Server/LoopDetectedException.php b/Exceptions/Http/Server/LoopDetectedException.php index 5732976..2050749 100644 --- a/Exceptions/Http/Server/LoopDetectedException.php +++ b/Exceptions/Http/Server/LoopDetectedException.php @@ -4,7 +4,7 @@ /** * This server detected that the request generated an endless loop while processing the request. This should be used - * only if you cannot properly throw a 403 before hand by detecting that the request would create an endless loop. + * only if you cannot properly throw a 403 beforehand by detecting that the request would create an endless loop. * * Never throw an exception at the user, always catch it can synthesize it to a correct html response with * appropriate headers. You can use the constants and accessor to get HTML values to return. @@ -17,10 +17,10 @@ class LoopDetectedException extends ServerErrorException /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 508; + public const HTTP_CODE = 508; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Loop Detected: The request is looping endlessly trying to produce the response.'; + public const HTTP_MESSAGE = 'Loop Detected: The request is looping endlessly trying to produce the response.'; } diff --git a/Exceptions/Http/Server/NotImplementedException.php b/Exceptions/Http/Server/NotImplementedException.php index 84849e0..2eb8ce5 100644 --- a/Exceptions/Http/Server/NotImplementedException.php +++ b/Exceptions/Http/Server/NotImplementedException.php @@ -16,10 +16,10 @@ class NotImplementedException extends ServerErrorException /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 501; + public const HTTP_CODE = 501; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Not Implemented: The server does not support the functionality required to fulfill the request.'; + public const HTTP_MESSAGE = 'Not Implemented: The server does not support the functionality required to fulfill the request.'; } diff --git a/Exceptions/Http/Server/ServerErrorException.php b/Exceptions/Http/Server/ServerErrorException.php index 1cd214e..fa902f9 100644 --- a/Exceptions/Http/Server/ServerErrorException.php +++ b/Exceptions/Http/Server/ServerErrorException.php @@ -3,18 +3,17 @@ namespace Exceptions\Http\Server; use Exceptions\Http\HttpException; -use Exceptions\Tag\AbortedTag; /** * All server error http exceptions extend this class and save you the trouble of setting up the method that returns * the error class code. */ -abstract class ServerErrorException extends HttpException implements ServerErrorExceptionInterface, AbortedTag +abstract class ServerErrorException extends HttpException implements ServerErrorExceptionInterface { /** * {@inheritdoc} */ - public static function getHttpCodeClass() + public static function getHttpCodeClass(): int { return self::CODE_CLASS_SERVER_ERROR; } diff --git a/Exceptions/Http/Server/ServiceUnavailableException.php b/Exceptions/Http/Server/ServiceUnavailableException.php index 0e5be40..3fdb38f 100644 --- a/Exceptions/Http/Server/ServiceUnavailableException.php +++ b/Exceptions/Http/Server/ServiceUnavailableException.php @@ -16,10 +16,10 @@ class ServiceUnavailableException extends ServerErrorException /** * Returns the HTTP error code for that exception. */ - const HTTP_CODE = 503; + public const HTTP_CODE = 503; /** * Returns the HTTP error message for that exception. */ - const HTTP_MESSAGE = 'Service Unavailable: The server is currently unable to handle the request due to a temporary overloading or maintenance of the server.'; + public const HTTP_MESSAGE = 'Service Unavailable: The server is currently unable to handle the request due to a temporary overloading or maintenance of the server.'; } diff --git a/Exceptions/IO/Filesystem/DirectoryAlreadyExistsException.php b/Exceptions/IO/Filesystem/DirectoryAlreadyExistsException.php index 9b4fb61..a2960d9 100644 --- a/Exceptions/IO/Filesystem/DirectoryAlreadyExistsException.php +++ b/Exceptions/IO/Filesystem/DirectoryAlreadyExistsException.php @@ -2,16 +2,16 @@ namespace Exceptions\IO\Filesystem; -use Exceptions\Tag\ExistsTag; +use Exceptions\Tag\AlreadyExistsTag; /** - * Use this exception when your code tries to create a local directory but it already exists. + * Use this exception when your code tries to create a local directory, but it already exists. * * @author Mathieu Dumoulin * @license MIT */ -class DirectoryAlreadyExistsException extends FilesystemException implements ExistsTag +class DirectoryAlreadyExistsException extends FilesystemException implements AlreadyExistsTag { - const MESSAGE = 'Cannot find specified directory'; - const CODE = 0; + public const MESSAGE = 'Cannot find specified directory'; + public const CODE = 0; } diff --git a/Exceptions/IO/Filesystem/DirectoryNotFoundException.php b/Exceptions/IO/Filesystem/DirectoryNotFoundException.php index c048b11..d205c96 100644 --- a/Exceptions/IO/Filesystem/DirectoryNotFoundException.php +++ b/Exceptions/IO/Filesystem/DirectoryNotFoundException.php @@ -12,6 +12,6 @@ */ class DirectoryNotFoundException extends FilesystemException implements NotFoundTag { - const MESSAGE = 'Cannot find specified directory'; - const CODE = 0; + public const MESSAGE = 'Cannot find specified directory'; + public const CODE = 0; } diff --git a/Exceptions/IO/Filesystem/DirectoryNotReadableException.php b/Exceptions/IO/Filesystem/DirectoryNotReadableException.php index 5db02e7..ea6219d 100644 --- a/Exceptions/IO/Filesystem/DirectoryNotReadableException.php +++ b/Exceptions/IO/Filesystem/DirectoryNotReadableException.php @@ -13,6 +13,6 @@ */ class DirectoryNotReadableException extends FilesystemException implements ForbiddenTag { - const MESSAGE = 'Cannot read from specified directory'; - const CODE = 0; + public const MESSAGE = 'Cannot read from specified directory'; + public const CODE = 0; } diff --git a/Exceptions/IO/Filesystem/DirectoryNotWritableException.php b/Exceptions/IO/Filesystem/DirectoryNotWritableException.php index 30a9889..399dbb6 100644 --- a/Exceptions/IO/Filesystem/DirectoryNotWritableException.php +++ b/Exceptions/IO/Filesystem/DirectoryNotWritableException.php @@ -13,6 +13,6 @@ */ class DirectoryNotWritableException extends FilesystemException implements ForbiddenTag { - const MESSAGE = 'Cannot write to specified directory'; - const CODE = 0; + public const MESSAGE = 'Cannot write to specified directory'; + public const CODE = 0; } diff --git a/Exceptions/IO/Filesystem/FileAlreadyExistsException.php b/Exceptions/IO/Filesystem/FileAlreadyExistsException.php index d979aa2..f6521e0 100644 --- a/Exceptions/IO/Filesystem/FileAlreadyExistsException.php +++ b/Exceptions/IO/Filesystem/FileAlreadyExistsException.php @@ -2,16 +2,16 @@ namespace Exceptions\IO\Filesystem; -use Exceptions\Tag\ExistsTag; +use Exceptions\Tag\AlreadyExistsTag; /** - * Use this exception when your code tries to create a file but it already exists. + * Use this exception when your code tries to create a file, but it already exists. * * @author Mathieu Dumoulin * @license MIT */ -class FileAlreadyExistsException extends FilesystemException implements ExistsTag +class FileAlreadyExistsException extends FilesystemException implements AlreadyExistsTag { - const MESSAGE = 'Cannot find specified file'; - const CODE = 0; + public const MESSAGE = 'Cannot find specified file'; + public const CODE = 0; } diff --git a/Exceptions/IO/Filesystem/FileNotFoundException.php b/Exceptions/IO/Filesystem/FileNotFoundException.php index 0fd5a0c..48a1ac8 100644 --- a/Exceptions/IO/Filesystem/FileNotFoundException.php +++ b/Exceptions/IO/Filesystem/FileNotFoundException.php @@ -12,6 +12,6 @@ */ class FileNotFoundException extends FilesystemException implements NotFoundTag { - const MESSAGE = 'Cannot find specified file'; - const CODE = 0; + public const MESSAGE = 'Cannot find specified file'; + public const CODE = 0; } diff --git a/Exceptions/IO/Filesystem/FileNotReadableException.php b/Exceptions/IO/Filesystem/FileNotReadableException.php index 9824886..aff6f83 100644 --- a/Exceptions/IO/Filesystem/FileNotReadableException.php +++ b/Exceptions/IO/Filesystem/FileNotReadableException.php @@ -12,6 +12,6 @@ */ class FileNotReadableException extends FilesystemException implements ForbiddenTag { - const MESSAGE = 'Cannot read from specified file'; - const CODE = 0; + public const MESSAGE = 'Cannot read from specified file'; + public const CODE = 0; } diff --git a/Exceptions/IO/Filesystem/FileNotWritableException.php b/Exceptions/IO/Filesystem/FileNotWritableException.php index 33cded8..da4f67a 100644 --- a/Exceptions/IO/Filesystem/FileNotWritableException.php +++ b/Exceptions/IO/Filesystem/FileNotWritableException.php @@ -13,6 +13,6 @@ */ class FileNotWritableException extends FilesystemException implements ForbiddenTag { - const MESSAGE = 'Cannot write to specified file'; - const CODE = 0; + public const MESSAGE = 'Cannot write to specified file'; + public const CODE = 0; } diff --git a/Exceptions/IO/Filesystem/NoMoreSpaceException.php b/Exceptions/IO/Filesystem/NoMoreSpaceException.php index 12f3d33..83bb90c 100644 --- a/Exceptions/IO/Filesystem/NoMoreSpaceException.php +++ b/Exceptions/IO/Filesystem/NoMoreSpaceException.php @@ -2,16 +2,14 @@ namespace Exceptions\IO\Filesystem; -use Exceptions\Tag\AbortedTag; - /** * Use this exception when your code realizes that there is no more space available on the device to write to. * * @author Mathieu Dumoulin * @license MIT */ -class NoMoreSpaceException extends FilesystemException implements AbortedTag +class NoMoreSpaceException extends FilesystemException { - const MESSAGE = 'Specified target location has run out of disk space'; - const CODE = 0; + public const MESSAGE = 'Specified target location has run out of disk space'; + public const CODE = 0; } diff --git a/Exceptions/IO/Filesystem/NotADirectoryException.php b/Exceptions/IO/Filesystem/NotADirectoryException.php index bbc23c9..fc26c47 100644 --- a/Exceptions/IO/Filesystem/NotADirectoryException.php +++ b/Exceptions/IO/Filesystem/NotADirectoryException.php @@ -12,6 +12,6 @@ */ class NotADirectoryException extends FilesystemException implements InvalidDataTag { - const MESSAGE = 'Specified path is not a directory'; - const CODE = 0; + public const MESSAGE = 'Specified path is not a directory'; + public const CODE = 0; } diff --git a/Exceptions/IO/Filesystem/NotAFileException.php b/Exceptions/IO/Filesystem/NotAFileException.php index a28fdfa..048a832 100644 --- a/Exceptions/IO/Filesystem/NotAFileException.php +++ b/Exceptions/IO/Filesystem/NotAFileException.php @@ -12,6 +12,6 @@ */ class NotAFileException extends FilesystemException implements InvalidDataTag { - const MESSAGE = 'Specified path is not a file'; - const CODE = 0; + public const MESSAGE = 'Specified path is not a file'; + public const CODE = 0; } diff --git a/Exceptions/IO/IOException.php b/Exceptions/IO/IOException.php index 2a87a51..839314a 100644 --- a/Exceptions/IO/IOException.php +++ b/Exceptions/IO/IOException.php @@ -2,10 +2,9 @@ namespace Exceptions\IO; -use Exceptions\Helpers\DefaultConstructorTrait; use Exceptions\Helpers\DefaultsInterface; -use Exceptions\Helpers\FromException; -use Exceptions\Helpers\WithContext; +use RuntimeException; +use Throwable; /** * This is a tag like class that is used to regroup all IO exceptions under a single base class. @@ -13,9 +12,19 @@ * @author Mathieu Dumoulin * @license MIT */ -abstract class IOException extends \RuntimeException implements IOExceptionInterface, DefaultsInterface +abstract class IOException extends RuntimeException implements IOExceptionInterface, DefaultsInterface { - use FromException, DefaultConstructorTrait, WithContext; + public function __construct( + string $message = "", + int $code = 0, + null|Throwable $previous = null + ) { + parent::__construct( + message: $message ?: $this->getDefaultMessage(), + code: $code ?: $this->getDefaultCode(), + previous: $previous + ); + } /** * {@inheritdoc} diff --git a/Exceptions/IO/Network/ConnectionLostException.php b/Exceptions/IO/Network/ConnectionLostException.php index fbb2da7..bdefff4 100644 --- a/Exceptions/IO/Network/ConnectionLostException.php +++ b/Exceptions/IO/Network/ConnectionLostException.php @@ -2,8 +2,6 @@ namespace Exceptions\IO\Network; -use Exceptions\Tag\AbortedTag; - /** * Use this exception when an IO operation that requires a distant connection gets cut off after negotiating * connection. @@ -11,8 +9,8 @@ * @author Mathieu Dumoulin * @license MIT */ -class ConnectionLostException extends NetworkException implements AbortedTag +class ConnectionLostException extends NetworkException { - const MESSAGE = 'Connection lost while exchanging data with remote host'; - const CODE = 0; + public const MESSAGE = 'Connection lost while exchanging data with remote host'; + public const CODE = 0; } diff --git a/Exceptions/IO/Network/ConnectionRefusedException.php b/Exceptions/IO/Network/ConnectionRefusedException.php index 84a9678..e6c90dd 100644 --- a/Exceptions/IO/Network/ConnectionRefusedException.php +++ b/Exceptions/IO/Network/ConnectionRefusedException.php @@ -13,6 +13,6 @@ */ class ConnectionRefusedException extends NetworkException implements ForbiddenTag { - const MESSAGE = 'Connection to remote host was refused'; - const CODE = 0; + public const MESSAGE = 'Connection to remote host was refused'; + public const CODE = 0; } diff --git a/Exceptions/IO/Network/ConnectionTimeoutException.php b/Exceptions/IO/Network/ConnectionTimeoutException.php index 3a2e932..c60749c 100644 --- a/Exceptions/IO/Network/ConnectionTimeoutException.php +++ b/Exceptions/IO/Network/ConnectionTimeoutException.php @@ -2,8 +2,6 @@ namespace Exceptions\IO\Network; -use Exceptions\Tag\AbortedTag; - /** * Use this exception when an IO network connection fails to connect in time. This exception is slightly different * from the RequestTimeoutException where it is the request that failed. @@ -11,8 +9,8 @@ * @author Mathieu Dumoulin * @license MIT */ -class ConnectionTimeoutException extends NetworkException implements AbortedTag +class ConnectionTimeoutException extends NetworkException { - const MESSAGE = 'Connection timed out while connecting to the remote host'; - const CODE = 0; + public const MESSAGE = 'Connection timed out while connecting to the remote host'; + public const CODE = 0; } diff --git a/Exceptions/IO/Network/RequestTimeoutException.php b/Exceptions/IO/Network/RequestTimeoutException.php index edd1a73..7650b7c 100644 --- a/Exceptions/IO/Network/RequestTimeoutException.php +++ b/Exceptions/IO/Network/RequestTimeoutException.php @@ -2,8 +2,6 @@ namespace Exceptions\IO\Network; -use Exceptions\Tag\AbortedTag; - /** * Use this exception when an IO network request fails to respond in time. This exception is slightly different * from the ConnectionTimeoutException where it is the connection to the host that failed. @@ -11,8 +9,8 @@ * @author Mathieu Dumoulin * @license MIT */ -class RequestTimeoutException extends NetworkException implements AbortedTag +class RequestTimeoutException extends NetworkException { - const MESSAGE = 'Request timed out while waiting for remote party to return response'; - const CODE = 0; + public const MESSAGE = 'Request timed out while waiting for remote party to return response'; + public const CODE = 0; } diff --git a/Exceptions/IO/Network/UnexpectedResponseException.php b/Exceptions/IO/Network/UnexpectedResponseException.php index 1fe1f9d..43053cc 100644 --- a/Exceptions/IO/Network/UnexpectedResponseException.php +++ b/Exceptions/IO/Network/UnexpectedResponseException.php @@ -2,8 +2,6 @@ namespace Exceptions\IO\Network; -use Exceptions\Tag\AbortedTag; - /** * Use this exception when an IO operation based on a communication protocol receives an unexpected response from * the remote host. @@ -14,8 +12,8 @@ * @author Mathieu Dumoulin * @license MIT */ -class UnexpectedResponseException extends NetworkException implements AbortedTag +class UnexpectedResponseException extends NetworkException { - const MESSAGE = 'Unexpected response received while communicating with remote host'; - const CODE = 0; + public const MESSAGE = 'Unexpected response received while communicating with remote host'; + public const CODE = 0; } diff --git a/Exceptions/IO/Network/UnknownHostException.php b/Exceptions/IO/Network/UnknownHostException.php index f2de1f8..dd1cc7a 100644 --- a/Exceptions/IO/Network/UnknownHostException.php +++ b/Exceptions/IO/Network/UnknownHostException.php @@ -13,6 +13,6 @@ */ class UnknownHostException extends NetworkException implements NotFoundTag { - const MESSAGE = 'The specified resource\'s hostname could not be resolved'; - const CODE = 0; + public const MESSAGE = 'The specified resource\'s hostname could not be resolved'; + public const CODE = 0; } diff --git a/Exceptions/Operation/AuthorizationException.php b/Exceptions/Operation/AuthorizationException.php index a796980..c0ac794 100644 --- a/Exceptions/Operation/AuthorizationException.php +++ b/Exceptions/Operation/AuthorizationException.php @@ -2,7 +2,6 @@ namespace Exceptions\Operation; -use Exceptions\Tag\AbortedTag; use Exceptions\Tag\UnauthorizedTag; /** @@ -20,8 +19,8 @@ * @author Mathieu Dumoulin aka CrazyCodr * @license MIT */ -class AuthorizationException extends OperationException implements AbortedTag, UnauthorizedTag +class AuthorizationException extends OperationException implements UnauthorizedTag { - const MESSAGE = 'Requested operation could not be executed because of a lack of permission'; - const CODE = 0; + public const MESSAGE = 'Requested operation could not be executed because of a lack of permission'; + public const CODE = 0; } diff --git a/Exceptions/Operation/ForbiddenException.php b/Exceptions/Operation/ForbiddenException.php index 5739594..de273fb 100644 --- a/Exceptions/Operation/ForbiddenException.php +++ b/Exceptions/Operation/ForbiddenException.php @@ -2,7 +2,6 @@ namespace Exceptions\Operation; -use Exceptions\Tag\AbortedTag; use Exceptions\Tag\ForbiddenTag; /** @@ -14,14 +13,14 @@ * that match the HTTP response code 403. You can still catch this and resolve the error the way you wish as catching * this error doesn't mean the whole request that was asked for should be denied. * - * Also note that permission errors should revolve around authorization exceptions but it is still very valid to use + * Also note that permission errors should revolve around authorization exceptions, but it is still very valid to use * forbidden exceptions in the context. The debate is fierce! * * @author Mathieu Dumoulin aka CrazyCodr * @license MIT */ -class ForbiddenException extends OperationException implements AbortedTag, ForbiddenTag +class ForbiddenException extends OperationException implements ForbiddenTag { - const MESSAGE = 'Requested operation could not be executed because of a lack of permission'; - const CODE = 0; + public const MESSAGE = 'Requested operation could not be executed because of a lack of permission'; + public const CODE = 0; } diff --git a/Exceptions/Operation/InvalidOperationException.php b/Exceptions/Operation/InvalidOperationException.php index 2aa7238..95175ab 100644 --- a/Exceptions/Operation/InvalidOperationException.php +++ b/Exceptions/Operation/InvalidOperationException.php @@ -5,18 +5,18 @@ use Exceptions\Tag\InvalidDataTag; /** - * Use this exception in the event something went wrong with the state of the application and you cannot allow + * Use this exception in the event something went wrong with the state of the application, and you cannot allow * executing this operation because of that state. For example, processing a report with no report specified would * yield an exception of type InvalidOperationException or something similar/custom based on it. This whole set of * exceptions didn't exist before but should have as many operations can end up being impossible to execute. * - * Use this exception sparingly and create sub exceptions of this exceptions to be more verbose when necessary. + * Use this exception sparingly and create sub exceptions to these exceptions to be more verbose when necessary. * * @author Mathieu Dumoulin * @license MIT */ class InvalidOperationException extends OperationException implements InvalidDataTag { - const MESSAGE = 'The attempted operation resulted in an unexpected/invalid state and cannot continue'; - const CODE = 0; + public const MESSAGE = 'The attempted operation resulted in an unexpected/invalid state and cannot continue'; + public const CODE = 0; } diff --git a/Exceptions/Operation/NotImplementedException.php b/Exceptions/Operation/NotImplementedException.php index 5afdf0c..c2216d5 100644 --- a/Exceptions/Operation/NotImplementedException.php +++ b/Exceptions/Operation/NotImplementedException.php @@ -2,8 +2,6 @@ namespace Exceptions\Operation; -use Exceptions\Tag\AbortedTag; - /** * Use this exception when someone is calling a function/method that is not implemented yet. This is a good practice * when implementing a lot of new functionality. Coupled to unit tests, you should not miss a NotImplementedException @@ -12,8 +10,8 @@ * @author Mathieu Dumoulin * @license MIT */ -class NotImplementedException extends OperationException implements AbortedTag +class NotImplementedException extends OperationException { - const MESSAGE = 'Feature not implemented yet'; - const CODE = 0; + public const MESSAGE = 'Feature not implemented yet'; + public const CODE = 0; } diff --git a/Exceptions/Operation/OperationException.php b/Exceptions/Operation/OperationException.php index fc3251a..49ee5db 100644 --- a/Exceptions/Operation/OperationException.php +++ b/Exceptions/Operation/OperationException.php @@ -2,10 +2,9 @@ namespace Exceptions\Operation; -use Exceptions\Helpers\DefaultConstructorTrait; use Exceptions\Helpers\DefaultsInterface; -use Exceptions\Helpers\FromException; -use Exceptions\Helpers\WithContext; +use RuntimeException; +use Throwable; /** * This is a tag like class that is used to regroup all Operation exceptions under a single base class. @@ -13,9 +12,19 @@ * @author Mathieu Dumoulin * @license MIT */ -abstract class OperationException extends \RuntimeException implements OperationExceptionInterface, DefaultsInterface +abstract class OperationException extends RuntimeException implements OperationExceptionInterface, DefaultsInterface { - use FromException, DefaultConstructorTrait, WithContext; + public function __construct( + string $message = "", + int $code = 0, + null|Throwable $previous = null + ) { + parent::__construct( + message: $message ?: $this->getDefaultMessage(), + code: $code ?: $this->getDefaultCode(), + previous: $previous + ); + } /** * {@inheritdoc} diff --git a/Exceptions/Operation/UnexpectedException.php b/Exceptions/Operation/UnexpectedException.php index c94605a..7ebc90c 100644 --- a/Exceptions/Operation/UnexpectedException.php +++ b/Exceptions/Operation/UnexpectedException.php @@ -2,12 +2,10 @@ namespace Exceptions\Operation; -use Exceptions\Tag\AbortedTag; - /** * Use this exception in the event that an operation that expected a certain result from a sub function/method call - * but did not get what i expected. This exception is the reversed validation exception. Instead of validating the - * user's input to a function, it is a means to signal that something went wrong when calling a sub components and + * but did not get what I expected. This exception is the reversed validation exception. Instead of validating the + * user's input to a function, it is a means to signal that something went wrong when calling a subcomponents and * the result is unexpected. * * It was created only for backwards compatibility with UnexpectedValueException. @@ -15,8 +13,8 @@ * @author Mathieu Dumoulin * @license MIT */ -class UnexpectedException extends OperationException implements AbortedTag +class UnexpectedException extends OperationException { - const MESSAGE = 'Unexpected value returned by internal call'; - const CODE = 0; + public const MESSAGE = 'Unexpected value returned by internal call'; + public const CODE = 0; } diff --git a/Exceptions/Tag/AbortedTag.php b/Exceptions/Tag/AbortedTag.php deleted file mode 100644 index 6f290e5..0000000 --- a/Exceptions/Tag/AbortedTag.php +++ /dev/null @@ -1,17 +0,0 @@ - - * @license MIT - */ -interface AbortedTag extends OperationAbortedException -{ -} diff --git a/Exceptions/Tag/AlreadyExistsException.php b/Exceptions/Tag/AlreadyExistsTag.php similarity index 92% rename from Exceptions/Tag/AlreadyExistsException.php rename to Exceptions/Tag/AlreadyExistsTag.php index 4c2a640..fc385b0 100644 --- a/Exceptions/Tag/AlreadyExistsException.php +++ b/Exceptions/Tag/AlreadyExistsTag.php @@ -10,6 +10,6 @@ * @author Mathieu Dumoulin * @license MIT */ -interface AlreadyExistsException +interface AlreadyExistsTag { } diff --git a/Exceptions/Tag/ExistsTag.php b/Exceptions/Tag/ExistsTag.php deleted file mode 100644 index 4ab3fc9..0000000 --- a/Exceptions/Tag/ExistsTag.php +++ /dev/null @@ -1,15 +0,0 @@ - - * @license MIT - */ -interface ExistsTag extends AlreadyExistsException -{ -} diff --git a/Exceptions/Tag/InvalidDataException.php b/Exceptions/Tag/InvalidDataException.php deleted file mode 100644 index 0c2a509..0000000 --- a/Exceptions/Tag/InvalidDataException.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @license MIT - */ -interface InvalidDataException -{ -} diff --git a/Exceptions/Tag/InvalidDataTag.php b/Exceptions/Tag/InvalidDataTag.php index 3d469e1..9a0692a 100644 --- a/Exceptions/Tag/InvalidDataTag.php +++ b/Exceptions/Tag/InvalidDataTag.php @@ -11,6 +11,6 @@ * @author Mathieu Dumoulin * @license MIT */ -interface InvalidDataTag extends InvalidDataException +interface InvalidDataTag { } diff --git a/Exceptions/Tag/NotFoundException.php b/Exceptions/Tag/NotFoundException.php deleted file mode 100644 index 2007003..0000000 --- a/Exceptions/Tag/NotFoundException.php +++ /dev/null @@ -1,17 +0,0 @@ - - * @license MIT - */ -interface NotFoundException -{ -} diff --git a/Exceptions/Tag/NotFoundTag.php b/Exceptions/Tag/NotFoundTag.php index 97a2fc1..154d3b5 100644 --- a/Exceptions/Tag/NotFoundTag.php +++ b/Exceptions/Tag/NotFoundTag.php @@ -10,6 +10,6 @@ * @author Mathieu Dumoulin * @license MIT */ -interface NotFoundTag extends NotFoundException +interface NotFoundTag { } diff --git a/Exceptions/Tag/OperationAbortedException.php b/Exceptions/Tag/OperationAbortedException.php deleted file mode 100644 index 6aaa3de..0000000 --- a/Exceptions/Tag/OperationAbortedException.php +++ /dev/null @@ -1,16 +0,0 @@ - - * @license MIT - */ -interface OperationAbortedException -{ -} diff --git a/Helpers/DefaultConstructorTrait.php b/Helpers/DefaultConstructorTrait.php deleted file mode 100644 index dc897fc..0000000 --- a/Helpers/DefaultConstructorTrait.php +++ /dev/null @@ -1,15 +0,0 @@ -getDefaultMessage(), $code ?: $this->getDefaultCode(), $previous); - } -} diff --git a/Helpers/DefaultsInterface.php b/Helpers/DefaultsInterface.php index 77dcf13..4deda86 100644 --- a/Helpers/DefaultsInterface.php +++ b/Helpers/DefaultsInterface.php @@ -1,4 +1,5 @@ Client\BadRequestException::class, - 401 => Client\UnauthorizedException::class, - 402 => Client\PaymentRequiredException::class, - 403 => Client\ForbiddenException::class, - 404 => Client\NotFoundException::class, - 405 => Client\MethodNotAllowedException::class, - 406 => Client\NotAcceptableException::class, - 407 => Client\ProxyAuthorizationRequiredException::class, - 408 => Client\RequestTimeoutException::class, - 409 => Client\ConflictException::class, - 410 => Client\GoneException::class, - 411 => Client\LengthRequiredException::class, - 412 => Client\PreConditionRequiredException::class, - 413 => Client\PayloadTooLargeException::class, - 414 => Client\URITooLongException::class, - 415 => Client\UnsupportedMediaTypeException::class, - 416 => Client\RangeNotSatisfiableException::class, - 417 => Client\ExpectationFailedException::class, - 418 => Client\ImATeapotException::class, - 421 => Client\MisdirectedRequestException::class, - 422 => Client\UnprocessableEntityException::class, - 423 => Client\LockedException::class, - 424 => Client\FailedDependencyException::class, - 426 => Client\UpgradeRequiredException::class, - 428 => Client\PreConditionRequiredException::class, - 429 => Client\TooManyRequestsException::class, - 431 => Client\RequestHeaderFieldsTooLargeException::class, - 451 => Client\UnavailableForLegalReasonsException::class, - 456 => Client\UnrecoverableErrorException::class, - 500 => Server\InternalServerErrorException::class, - 501 => Server\NotImplementedException::class, - 502 => Server\BadGatewayException::class, - 503 => Server\ServiceUnavailableException::class, - 504 => Server\GatewayTimeoutException::class, - 505 => Server\HttpVersionNotSupportedException::class, - 507 => Server\InsuficientStorageException::class, - 508 => Server\LoopDetectedException::class, - ]; - - /** - * @param int $responseCode - * @param string|null $message - * @param Throwable|null $ex - * @return HttpExceptionInterface - * - * @throws ValidationException When {$responseCode} can't be mapped to an HttpException - */ - public static function build(int $responseCode, string $message = '', Throwable $ex = null): HttpExceptionInterface - { - $mapping = static::getMapping(); - if (!array_key_exists($responseCode, $mapping)) { - throw new ValidationException('Unknown mapping for response code ' . $responseCode); - } - - return new $mapping[$responseCode]($message, $responseCode, $ex); - } - - /** - * @param int $responseCode - * @param mixed $context mixed data you can attach to the exception - * @param string|null $message - * @param Throwable|null $ex [optional] The previous throwable used for the exception chaining. - * @return HttpExceptionInterface - * - * @throws ValidationException When {$responseCode} can't be mapped to an HttpException - */ - public static function buildWithContext(int $responseCode, $context, string $message = '', Throwable $ex = null): HttpExceptionInterface - { - $mapping = static::getMapping(); - if (!array_key_exists($responseCode, $mapping)) { - throw new ValidationException('Unknown mapping for response code ' . $responseCode); - } - - return $mapping[$responseCode]::withContext($context, $message, $responseCode, $ex); - } - - /** - * @return array Map between a an Error code (as key) and a Class name (as value) - */ - protected static function getMapping(): array - { - return static::$mapping; - } -} diff --git a/Helpers/WithContext.php b/Helpers/WithContext.php deleted file mode 100644 index e26773d..0000000 --- a/Helpers/WithContext.php +++ /dev/null @@ -1,48 +0,0 @@ -context = $context; - return $ex; - } - - /** - * Returns the saved context from the exception - * - * @return mixed - */ - public function getContext() - { - return $this->context; - } -} diff --git a/README.md b/README.md index 1b68436..56dd69b 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,26 @@ -[![Latest Stable Version](https://poser.pugx.org/crazycodr/standard-exceptions/version.png)](https://packagist.org/packages/crazycodr/standard-exceptions) [![Monthly Downloads](https://poser.pugx.org/crazycodr/standard-exceptions/d/monthly)](https://packagist.org/packages/crazycodr/standard-exceptions) [![Build Status](https://travis-ci.org/crazycodr/standard-exceptions.png?branch=master)](https://travis-ci.org/crazycodr/standard-exceptions) +[![Latest Stable Version](https://poser.pugx.org/crazycodr/standard-exceptions/version.png)](https://packagist.org/packages/crazycodr/standard-exceptions) [![Monthly Downloads](https://poser.pugx.org/crazycodr/standard-exceptions/d/monthly)](https://packagist.org/packages/crazycodr/standard-exceptions) # Standard Exceptions Package -This project is aimed at providing additional standard exceptions to [PHP](http://www.php.net/). +This project is aimed at providing additional standard exceptions to [PHP](http://www.php.net/). Many exceptions that are missing from the SPL are constantly being reproduced in different projects. By providing a package of high-quality, well organised exceptions, it will, in the long run, increase interoperability between projects and libraries. -# Getting started - -To install `Standard Exceptions`, just require it using [Composer](http://www.getcomposer.org/): - -``` -$ composer require crazycodr/standard-exceptions -``` - -And then just start throwing exceptions: - -```php -throw new \Exceptions\Data\NotFoundException(); -``` - -Or catch them: - -```php -try { - -} catch(\Exceptions\Data\NotFoundExceptions $ex){ - -} -``` - -Or even better, catch exceptions with similar means: - -```php -try { - -} catch(\Exceptions\Tag\NotFoundTag $ex){ - -} -``` - -For more information, visit the [Getting Started Page](docs/getting-started.md) or for even more information, you get read the whole [Documentation](docs/index.md). - -If you need help upgrading for the old version 1 to this version, see the [Upgrading from Version 1 to Version 2](docs/upgrade-1-2.md) documentation page. - -# Features - -* Highly comprehensive list of exceptions and namespaces: [Browse](docs/exceptions/) -* [Tag interfaces](docs/tags.md) to catch common exceptions with similar means but different contexts -* Exceptions define default messages and error codes using the [DefaultsInterface and DefaultConstructorTrait](docs/helpers.md) -* Throwing new exceptions from another exception allows easier exception chaining using [FromException helper](docs/helpers.md) - -# Contribution - -Don't hesitate to contribute to this package by: - -* Proposing new exceptions or namespaces -* Fix documentation issues or bugs by opening PRs -* Using it and spreading it's use throughout projects and libraries - - -If you want to contribute to the code base go to the [Contributing page](docs/contribute.md). +# Table of contents + +* [Getting started](docs/getting-started.md) + * [Upgrading from version 1 to version 2](docs/upgrade-1-2.md) + * [Upgrading from version 2 to version 3](docs/upgrade-2-3.md) +* Exceptions and namespaces + * [Collection exceptions](docs/exceptions/collection-exceptions.md) + * [Data exceptions](docs/exceptions/data-exceptions.md) + * HTTP exceptions + * [HTTP client exceptions (400s)](docs/exceptions/http-client-exceptions.md) + * [HTTP server exceptions (500s)](docs/exceptions/http-server-exceptions.md) + * IO exceptions + * [Filesystem exceptions](docs/exceptions/io-filesystem-exceptions.md) + * [Network exceptions](docs/exceptions/io-network-exceptions.md) + * [Operation exceptions](docs/exceptions/operation-exceptions.md) +* [Tags](docs/tags.md) +* [Patterns](docs/patterns.md) +* [Contributing](docs/contribute.md) diff --git a/Tests/DependencyTest.php b/Tests/DependencyTest.php deleted file mode 100644 index bc55bed..0000000 --- a/Tests/DependencyTest.php +++ /dev/null @@ -1,781 +0,0 @@ -getDependenciesFor(Tag\OperationAbortedException::class) - ); - case Tag\InvalidDataTag::class: - return array_merge( - [$className], - $this->getDependenciesFor(Tag\InvalidDataException::class) - ); - case Tag\NotFoundTag::class: - return array_merge( - [$className], - $this->getDependenciesFor(Tag\NotFoundException::class) - ); - case Tag\ExistsTag::class: - return array_merge( - [$className], - $this->getDependenciesFor(Tag\AlreadyExistsException::class) - ); - - // Resolution of high level exception class dependencies - case Collection\CollectionException::class: - return array_merge( - [$className], - $this->getDependenciesFor(RuntimeException::class), - $this->getDependenciesFor(Collection\CollectionExceptionInterface::class), - $this->getDependenciesFor(Helpers\DefaultsInterface::class), - $this->getDependenciesFor(Helpers\FromException::class), - $this->getDependenciesFor(Helpers\WithContext::class), - $this->getDependenciesFor(Helpers\DefaultConstructorTrait::class) - ); - case Data\DataException::class: - return array_merge( - [$className], - $this->getDependenciesFor(RuntimeException::class), - $this->getDependenciesFor(Data\DataExceptionInterface::class), - $this->getDependenciesFor(Helpers\DefaultsInterface::class), - $this->getDependenciesFor(Helpers\FromException::class), - $this->getDependenciesFor(Helpers\WithContext::class), - $this->getDependenciesFor(Helpers\DefaultConstructorTrait::class) - ); - case Http\HttpException::class: - return array_merge( - [$className], - $this->getDependenciesFor(RuntimeException::class), - $this->getDependenciesFor(Http\HttpExceptionInterface::class), - $this->getDependenciesFor(Helpers\DefaultsInterface::class), - $this->getDependenciesFor(Helpers\FromException::class), - $this->getDependenciesFor(Helpers\WithContext::class), - $this->getDependenciesFor(Helpers\DefaultConstructorTrait::class) - ); - case Http\Client\ClientErrorException::class: - return array_merge( - [$className], - $this->getDependenciesFor(Http\HttpException::class), - $this->getDependenciesFor(Http\Client\ClientErrorExceptionInterface::class), - $this->getDependenciesFor(Tag\AbortedTag::class) - ); - case Http\Server\ServerErrorException::class: - return array_merge( - [$className], - $this->getDependenciesFor(Http\HttpException::class), - $this->getDependenciesFor(Http\Server\ServerErrorExceptionInterface::class), - $this->getDependenciesFor(Tag\AbortedTag::class) - ); - case IO\IOException::class: - return array_merge( - [$className], - $this->getDependenciesFor(RuntimeException::class), - $this->getDependenciesFor(IO\IOExceptionInterface::class), - $this->getDependenciesFor(Helpers\DefaultsInterface::class), - $this->getDependenciesFor(Helpers\FromException::class), - $this->getDependenciesFor(Helpers\WithContext::class), - $this->getDependenciesFor(Helpers\DefaultConstructorTrait::class) - ); - case IO\Filesystem\FilesystemException::class: - return array_merge( - [$className], - $this->getDependenciesFor(IO\IOException::class), - $this->getDependenciesFor(IO\Filesystem\FilesystemExceptionInterface::class) - ); - case IO\Network\NetworkException::class: - return array_merge( - [$className], - $this->getDependenciesFor(IO\IOException::class), - $this->getDependenciesFor(IO\Network\NetworkExceptionInterface::class) - ); - case Operation\OperationException::class: - return array_merge( - [$className], - $this->getDependenciesFor(RuntimeException::class), - $this->getDependenciesFor(Operation\OperationExceptionInterface::class), - $this->getDependenciesFor(Helpers\DefaultsInterface::class), - $this->getDependenciesFor(Helpers\FromException::class), - $this->getDependenciesFor(Helpers\WithContext::class), - $this->getDependenciesFor(Helpers\DefaultConstructorTrait::class) - ); - - // If the class is not listed, then just return itself to be merged into the parent list - default: - return [$className]; - } - } - - /** - * @return mixed[] - */ - public function providesDependencies() - { - - // Will contain all scenarios to test with the class name to test and an array of all classes this class - // should depend on - $dependencies = []; - - // New tag dependencies to ensure backwards compatibility with new tags acting as renames over deprecated ones - $dependencies[Tag\NotFoundTag::class] = [ - Tag\NotFoundTag::class, - array_merge( - $this->getDependenciesFor(Tag\NotFoundException::class) - ), - ]; - $dependencies[Tag\AbortedTag::class] = [ - Tag\AbortedTag::class, - array_merge( - $this->getDependenciesFor(Tag\OperationAbortedException::class) - ), - ]; - $dependencies[Tag\InvalidDataTag::class] = [ - Tag\InvalidDataTag::class, - array_merge( - $this->getDependenciesFor(Tag\InvalidDataException::class) - ), - ]; - - // Collection exception dependencies - $dependencies[Collection\EmptyException::class] = [ - Collection\EmptyException::class, - array_merge( - $this->getDependenciesFor(Collection\CollectionException::class) - ), - ]; - $dependencies[Collection\FullException::class] = [ - Collection\FullException::class, - array_merge( - $this->getDependenciesFor(Collection\CollectionException::class) - ), - ]; - $dependencies[Collection\KeyAlreadyExistsException::class] = [ - Collection\KeyAlreadyExistsException::class, - array_merge( - $this->getDependenciesFor(Collection\CollectionException::class), - $this->getDependenciesFor(Tag\ExistsTag::class) - ), - ]; - $dependencies[Collection\KeyNotFoundException::class] = [ - Collection\KeyNotFoundException::class, - array_merge( - $this->getDependenciesFor(Collection\CollectionException::class), - $this->getDependenciesFor(Tag\NotFoundTag::class) - ), - ]; - $dependencies[Collection\ReadOnlyArrayException::class] = [ - Collection\ReadOnlyArrayException::class, - array_merge( - $this->getDependenciesFor(Collection\CollectionException::class) - ), - ]; - $dependencies[Collection\ReadOnlyArrayItemException::class] = [ - Collection\ReadOnlyArrayItemException::class, - array_merge( - $this->getDependenciesFor(Collection\CollectionException::class) - ), - ]; - - // Data exception dependencies - $dependencies[Data\FormatException::class] = [ - Data\FormatException::class, - array_merge( - $this->getDependenciesFor(Data\DataException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Data\FoundTooLittleException::class] = [ - Data\FoundTooLittleException::class, - array_merge( - $this->getDependenciesFor(Data\DataException::class) - ), - ]; - $dependencies[Data\FoundTooManyException::class] = [ - Data\FoundTooManyException::class, - array_merge( - $this->getDependenciesFor(Data\DataException::class) - ), - ]; - $dependencies[Data\IntegrityException::class] = [ - Data\IntegrityException::class, - array_merge( - $this->getDependenciesFor(Data\DataException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Data\NotFoundException::class] = [ - Data\NotFoundException::class, - array_merge( - $this->getDependenciesFor(Data\DataException::class), - $this->getDependenciesFor(Tag\NotFoundTag::class) - ), - ]; - $dependencies[Data\TypeException::class] = [ - Data\TypeException::class, - array_merge( - $this->getDependenciesFor(Data\DataException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - - // Http client exception dependencies - $dependencies[Http\Client\BadRequestException::class] = [ - Http\Client\BadRequestException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Http\Client\ConflictException::class] = [ - Http\Client\ConflictException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Http\Client\ExpectationFailedException::class] = [ - Http\Client\ExpectationFailedException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Http\Client\FailedDependencyException::class] = [ - Http\Client\FailedDependencyException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class) - ), - ]; - $dependencies[Http\Client\ForbiddenException::class] = [ - Http\Client\ForbiddenException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\ForbiddenTag::class) - ), - ]; - $dependencies[Http\Client\GoneException::class] = [ - Http\Client\GoneException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\NotFoundTag::class) - ), - ]; - $dependencies[Http\Client\ImATeapotException::class] = [ - Http\Client\ImATeapotException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class) - ), - ]; - $dependencies[Http\Client\LengthRequiredException::class] = [ - Http\Client\LengthRequiredException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Http\Client\LockedException::class] = [ - Http\Client\LockedException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\ForbiddenTag::class) - ), - ]; - $dependencies[Http\Client\MethodNotAllowedException::class] = [ - Http\Client\MethodNotAllowedException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Http\Client\MisdirectedRequestException::class] = [ - Http\Client\MisdirectedRequestException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class) - ), - ]; - $dependencies[Http\Client\NotAcceptableException::class] = [ - Http\Client\NotAcceptableException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Http\Client\NotFoundException::class] = [ - Http\Client\NotFoundException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\NotFoundTag::class) - ), - ]; - $dependencies[Http\Client\PaymentRequiredException::class] = [ - Http\Client\PaymentRequiredException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\ForbiddenTag::class) - ), - ]; - $dependencies[Http\Client\PreConditionFailedException::class] = [ - Http\Client\PreConditionFailedException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Http\Client\PreConditionRequiredException::class] = [ - Http\Client\PreConditionRequiredException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Http\Client\ProxyAuthorizationRequiredException::class] = [ - Http\Client\ProxyAuthorizationRequiredException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\UnauthorizedTag::class) - ), - ]; - $dependencies[Http\Client\RequestedRangeNotSatisfiableException::class] = [ - Http\Client\RequestedRangeNotSatisfiableException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Http\Client\RangeNotSatisfiableException::class] = [ - Http\Client\RangeNotSatisfiableException::class, - array_merge( - [Http\Client\RequestedRangeNotSatisfiableException::class], - $dependencies[Http\Client\RequestedRangeNotSatisfiableException::class][1] - ), - ]; - $dependencies[Http\Client\RequestEntityTooLargeException::class] = [ - Http\Client\RequestEntityTooLargeException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Http\Client\PayloadTooLargeException::class] = [ - Http\Client\PayloadTooLargeException::class, - array_merge( - [Http\Client\RequestEntityTooLargeException::class], - $dependencies[Http\Client\RequestEntityTooLargeException::class][1] - ), - ]; - $dependencies[Http\Client\RequestHeaderFieldsTooLargeException::class] = [ - Http\Client\RequestHeaderFieldsTooLargeException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Http\Client\RequestTimeoutException::class] = [ - Http\Client\RequestTimeoutException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class) - ), - ]; - $dependencies[Http\Client\TooManyRequestsException::class] = [ - Http\Client\TooManyRequestsException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\ForbiddenTag::class) - ), - ]; - $dependencies[Http\Client\UnauthorizedException::class] = [ - Http\Client\UnauthorizedException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\UnauthorizedTag::class) - ), - ]; - $dependencies[Http\Client\UnavailableForLegalReasonsException::class] = [ - Http\Client\UnavailableForLegalReasonsException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\ForbiddenTag::class) - ), - ]; - $dependencies[Http\Client\UnprocessableEntityException::class] = [ - Http\Client\UnprocessableEntityException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Http\Client\UnsupportedMediaTypeException::class] = [ - Http\Client\UnsupportedMediaTypeException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Http\Client\UpgradeRequiredException::class] = [ - Http\Client\UpgradeRequiredException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Http\Client\URITooLongException::class] = [ - Http\Client\URITooLongException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Http\Client\UnrecoverableErrorException::class] = [ - Http\Client\UnrecoverableErrorException::class, - array_merge( - $this->getDependenciesFor(Http\Client\ClientErrorException::class), - $this->getDependenciesFor(Tag\AbortedTag::class) - ), - ]; - - // Http server exception dependencies - $dependencies[Http\Server\BadGatewayException::class] = [ - Http\Server\BadGatewayException::class, - array_merge( - $this->getDependenciesFor(Http\Server\ServerErrorException::class) - ), - ]; - $dependencies[Http\Server\GatewayTimeoutException::class] = [ - Http\Server\GatewayTimeoutException::class, - array_merge( - $this->getDependenciesFor(Http\Server\ServerErrorException::class) - ), - ]; - $dependencies[Http\Server\HttpVersionNotSupportedException::class] = [ - Http\Server\HttpVersionNotSupportedException::class, - array_merge( - $this->getDependenciesFor(Http\Server\ServerErrorException::class) - ), - ]; - $dependencies[Http\Server\InsuficientStorageException::class] = [ - Http\Server\InsuficientStorageException::class, - array_merge( - $this->getDependenciesFor(Http\Server\ServerErrorException::class) - ), - ]; - $dependencies[Http\Server\InternalServerErrorException::class] = [ - Http\Server\InternalServerErrorException::class, - array_merge( - $this->getDependenciesFor(Http\Server\ServerErrorException::class) - ), - ]; - $dependencies[Http\Server\LoopDetectedException::class] = [ - Http\Server\LoopDetectedException::class, - array_merge( - $this->getDependenciesFor(Http\Server\ServerErrorException::class) - ), - ]; - $dependencies[Http\Server\NotImplementedException::class] = [ - Http\Server\NotImplementedException::class, - array_merge( - $this->getDependenciesFor(Http\Server\ServerErrorException::class) - ), - ]; - $dependencies[Http\Server\ServiceUnavailableException::class] = [ - Http\Server\ServiceUnavailableException::class, - array_merge( - $this->getDependenciesFor(Http\Server\ServerErrorException::class) - ), - ]; - - // Filesystem exception dependencies - $dependencies[IO\Filesystem\DirectoryAlreadyExistsException::class] = [ - IO\Filesystem\DirectoryAlreadyExistsException::class, - array_merge( - $this->getDependenciesFor(IO\Filesystem\FilesystemException::class), - $this->getDependenciesFor(Tag\ExistsTag::class) - ), - ]; - $dependencies[IO\Filesystem\DirectoryNotFoundException::class] = [ - IO\Filesystem\DirectoryNotFoundException::class, - array_merge( - $this->getDependenciesFor(IO\Filesystem\FilesystemException::class), - $this->getDependenciesFor(Tag\NotFoundTag::class) - ), - ]; - $dependencies[IO\Filesystem\DirectoryNotReadableException::class] = [ - IO\Filesystem\DirectoryNotReadableException::class, - array_merge( - $this->getDependenciesFor(IO\Filesystem\FilesystemException::class), - $this->getDependenciesFor(Tag\ForbiddenTag::class) - ), - ]; - $dependencies[IO\Filesystem\DirectoryNotWritableException::class] = [ - IO\Filesystem\DirectoryNotWritableException::class, - array_merge( - $this->getDependenciesFor(IO\Filesystem\FilesystemException::class), - $this->getDependenciesFor(Tag\ForbiddenTag::class) - ), - ]; - $dependencies[IO\Filesystem\FileAlreadyExistsException::class] = [ - IO\Filesystem\FileAlreadyExistsException::class, - array_merge( - $this->getDependenciesFor(IO\Filesystem\FilesystemException::class), - $this->getDependenciesFor(Tag\ExistsTag::class) - ), - ]; - $dependencies[IO\Filesystem\FileNotFoundException::class] = [ - IO\Filesystem\FileNotFoundException::class, - array_merge( - $this->getDependenciesFor(IO\Filesystem\FilesystemException::class), - $this->getDependenciesFor(Tag\NotFoundTag::class) - ), - ]; - $dependencies[IO\Filesystem\FileNotReadableException::class] = [ - IO\Filesystem\FileNotReadableException::class, - array_merge( - $this->getDependenciesFor(IO\Filesystem\FilesystemException::class), - $this->getDependenciesFor(Tag\ForbiddenTag::class) - ), - ]; - $dependencies[IO\Filesystem\FileNotWritableException::class] = [ - IO\Filesystem\FileNotWritableException::class, - array_merge( - $this->getDependenciesFor(IO\Filesystem\FilesystemException::class), - $this->getDependenciesFor(Tag\ForbiddenTag::class) - ), - ]; - $dependencies[IO\Filesystem\NoMoreSpaceException::class] = [ - IO\Filesystem\NoMoreSpaceException::class, - array_merge( - $this->getDependenciesFor(IO\Filesystem\FilesystemException::class), - $this->getDependenciesFor(Tag\AbortedTag::class) - ), - ]; - $dependencies[IO\Filesystem\NotADirectoryException::class] = [ - IO\Filesystem\NotADirectoryException::class, - array_merge( - $this->getDependenciesFor(IO\Filesystem\FilesystemException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[IO\Filesystem\NotAFileException::class] = [ - IO\Filesystem\NotAFileException::class, - array_merge( - $this->getDependenciesFor(IO\Filesystem\FilesystemException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - - // Network exception dependencies - $dependencies[IO\Network\ConnectionLostException::class] = [ - IO\Network\ConnectionLostException::class, - array_merge( - $this->getDependenciesFor(IO\Network\NetworkException::class), - $this->getDependenciesFor(Tag\AbortedTag::class) - ), - ]; - $dependencies[IO\Network\ConnectionRefusedException::class] = [ - IO\Network\ConnectionRefusedException::class, - array_merge( - $this->getDependenciesFor(IO\Network\NetworkException::class), - $this->getDependenciesFor(Tag\ForbiddenTag::class) - ), - ]; - $dependencies[IO\Network\ConnectionTimeoutException::class] = [ - IO\Network\ConnectionTimeoutException::class, - array_merge( - $this->getDependenciesFor(IO\Network\NetworkException::class), - $this->getDependenciesFor(Tag\AbortedTag::class) - ), - ]; - $dependencies[IO\Network\RequestTimeoutException::class] = [ - IO\Network\RequestTimeoutException::class, - array_merge( - $this->getDependenciesFor(IO\Network\NetworkException::class), - $this->getDependenciesFor(Tag\AbortedTag::class) - ), - ]; - $dependencies[IO\Network\UnexpectedResponseException::class] = [ - IO\Network\UnexpectedResponseException::class, - array_merge( - $this->getDependenciesFor(IO\Network\NetworkException::class), - $this->getDependenciesFor(Tag\AbortedTag::class) - ), - ]; - $dependencies[IO\Network\UnknownHostException::class] = [ - IO\Network\UnknownHostException::class, - array_merge( - $this->getDependenciesFor(IO\Network\NetworkException::class), - $this->getDependenciesFor(Tag\NotFoundTag::class) - ), - ]; - - // Operation exception dependencies - $dependencies[Operation\AuthorizationException::class] = [ - Operation\AuthorizationException::class, - array_merge( - $this->getDependenciesFor(Operation\OperationException::class), - $this->getDependenciesFor(Tag\AbortedTag::class), - $this->getDependenciesFor(Tag\UnauthorizedTag::class) - ), - ]; - $dependencies[Operation\ForbiddenException::class] = [ - Operation\ForbiddenException::class, - array_merge( - $this->getDependenciesFor(Operation\OperationException::class), - $this->getDependenciesFor(Tag\AbortedTag::class), - $this->getDependenciesFor(Tag\ForbiddenTag::class) - ), - ]; - $dependencies[Operation\InvalidOperationException::class] = [ - Operation\InvalidOperationException::class, - array_merge( - $this->getDependenciesFor(Operation\OperationException::class), - $this->getDependenciesFor(Tag\InvalidDataTag::class) - ), - ]; - $dependencies[Operation\NotImplementedException::class] = [ - Operation\NotImplementedException::class, - array_merge( - $this->getDependenciesFor(Operation\OperationException::class), - $this->getDependenciesFor(Tag\AbortedTag::class) - ), - ]; - $dependencies[Operation\UnexpectedException::class] = [ - Operation\UnexpectedException::class, - array_merge( - $this->getDependenciesFor(Operation\OperationException::class), - $this->getDependenciesFor(Tag\AbortedTag::class) - ), - ]; - - return $dependencies; - } - - /** - * @dataProvider providesDependencies - * - * @param string $className Class to test dependencies for - * @param string[] $declaredDependencies that the class should use directly or through parents - */ - public function testDependencies(string $className, array $declaredDependencies) - { - - // Find the parent items - $testedClass = new ReflectionClass($className); - - // Massage data for easier visuals in case something breaks - $foundDependencies = array_merge( - array_unique(array_map(function (ReflectionClass $x) { - return $x->getName(); - }, $this->getParentClasses($testedClass))), - array_unique(array_map(function (ReflectionClass $x) { - return $x->getName(); - }, $this->getParentInterfaces($testedClass))), - array_unique(array_map(function (ReflectionClass $x) { - return $x->getName(); - }, $this->getParentTraits($testedClass))) - ); - sort($foundDependencies); - sort($declaredDependencies); - - // Find the extra and missing items - $missingDependencies = array_diff($declaredDependencies, $foundDependencies); - $extraDependencies = array_diff($foundDependencies, $declaredDependencies); - sort($missingDependencies); - sort($extraDependencies); - - // Assert - $this->assertCount( - 0, - $missingDependencies, - 'Class ' . $className . ' has missing declared dependencies' . PHP_EOL - . 'Found dependencies: ' . print_r($foundDependencies, true) . PHP_EOL - . 'Declared dependencies: ' . print_r($declaredDependencies, true) . PHP_EOL - . 'Missing dependencies: ' . print_r($missingDependencies, true) . PHP_EOL - ); - $this->assertCount( - 0, - $extraDependencies, - 'Class ' . $className . ' has extra undeclared dependencies' . PHP_EOL - . 'Found dependencies: ' . print_r($foundDependencies, true) . PHP_EOL - . 'Declared dependencies: ' . print_r($declaredDependencies, true) . PHP_EOL - . 'Extra dependencies: ' . print_r($extraDependencies, true) . PHP_EOL - ); - } - - /** - * @param ReflectionClass $class - * - * @return ReflectionClass[] - */ - public function getParentClasses(ReflectionClass $class): array - { - $parents = []; - while ($parent = $class->getParentClass()) { - $parents[] = $parent; - $class = $parent; - } - return array_filter($parents, function (ReflectionClass $x) { - return $x->getName() == 'RuntimeException' - || substr($x->getName(), 0, strlen('Exceptions\\')) == 'Exceptions\\'; - }); - } - - /** - * @param ReflectionClass $class - * - * @return ReflectionClass[] - */ - public function getParentInterfaces(ReflectionClass $class): array - { - $interfaces = $class->getInterfaces(); - foreach ($this->getParentClasses($class) as $parent) { - $interfaces = array_merge($interfaces, $parent->getInterfaces()); - } - return array_filter($interfaces, function (ReflectionClass $x) { - return $x->getName() == 'RuntimeException' - || substr($x->getName(), 0, strlen('Exceptions\\')) == 'Exceptions\\'; - }); - } - - /** - * @param ReflectionClass $class - * - * @return ReflectionClass[] - */ - public function getParentTraits(ReflectionClass $class): array - { - $traits = $class->getTraits(); - foreach ($this->getParentClasses($class) as $parent) { - $traits = array_merge($traits, $parent->getTraits()); - } - return array_filter($traits, function (ReflectionClass $x) { - return $x->getName() == 'RuntimeException' - || substr($x->getName(), 0, strlen('Exceptions\\')) == 'Exceptions\\'; - }); - } -} diff --git a/Tests/FeatureTest.php b/Tests/FeatureTest.php deleted file mode 100644 index f5c7dcc..0000000 --- a/Tests/FeatureTest.php +++ /dev/null @@ -1,113 +0,0 @@ -assertEquals('Test message passed', $exception->getMessage()); - $this->assertEquals(92837, $exception->getCode()); - $this->assertSame($previousException, $exception->getPrevious()); - } - - /** - * Tests that you can call get default message and get default code - */ - public function testDefaults() - { - $this->assertNotEmpty(Collection\EmptyException::getDefaultMessage()); - $this->assertNotNull(Collection\EmptyException::getDefaultCode()); - } - - /** - * Tests that on a new parameter less constructed exception, the message and code should match the defaults - */ - public function testDefaultConstructor() - { - $exception = new Collection\EmptyException(); - $this->assertEquals($exception->getMessage(), Collection\EmptyException::getDefaultMessage()); - $this->assertEquals($exception->getCode(), Collection\EmptyException::getDefaultCode()); - } - - /** - * Tests that using from() will create a new exception with default message/code but still add the previous - * exception passed in properly. - */ - public function testFromException() - { - $previousException = new \Exception('test'); - /** @var \Exception $exception */ - $exception = Collection\EmptyException::from($previousException); - $this->assertEquals(Collection\EmptyException::getDefaultMessage(), $exception->getMessage()); - $this->assertEquals(Collection\EmptyException::getDefaultCode(), $exception->getCode()); - $this->assertSame($previousException, $exception->getPrevious()); - } - - /** - * Tests that using withContext() will create a new exception with default message/code and add context data - * to the exception and allow the retrieval of it. - */ - public function testWithContextException() - { - /** @var \Exception $exception */ - $exception = Collection\EmptyException::withContext([ - 'key1' => 'data1', - ]); - $this->assertEquals(Collection\EmptyException::getDefaultMessage(), $exception->getMessage()); - $this->assertEquals(Collection\EmptyException::getDefaultCode(), $exception->getCode()); - $this->assertEquals([ - 'key1' => 'data1', - ], $exception->getContext()); - } - - /** - * Tests that the getHttpCode and getHttpMessages can be called on Http exceptions - */ - public function testHttpMethods() - { - $this->assertContains(Http\Client\ForbiddenException::getHttpCodeClass(), [ - Http\HttpExceptionInterface::CODE_CLASS_CLIENT_ERROR, - Http\HttpExceptionInterface::CODE_CLASS_SERVER_ERROR, - ]); - $this->assertClassIsSubclassOf( - Http\HttpExceptionInterface::class, - Http\Client\ForbiddenException::class - ); - $this->assertInternalType('int', Http\Client\ForbiddenException::getHttpCode()); - $this->assertGreaterThan(0, Http\Client\ForbiddenException::getHttpCode()); - $this->assertInternalType('string', Http\Client\ForbiddenException::getHttpMessage()); - $this->assertGreaterThan(0, strlen(Http\Client\ForbiddenException::getHttpMessage())); - } - - /** - * Used to test that the $expected class is part of the $subject class anywhere in the class hierarchy - * - * @param string $expected Class to expect $subject to extend - * @param string $subject Class that should extend $expected - * - * @throws ReflectionException - */ - public function assertClassIsSubclassOf(string $expected, string $subject) - { - $checkReflection = new ReflectionClass($subject); - $expectedReflection = new ReflectionClass($expected); - $this->assertTrue( - $checkReflection->isSubclassOf($expectedReflection), - $subject . ' is not a subclass of ' . $expected - ); - } -} diff --git a/Tests/HttpExceptionFactoryTest.php b/Tests/HttpExceptionFactoryTest.php deleted file mode 100644 index 957a677..0000000 --- a/Tests/HttpExceptionFactoryTest.php +++ /dev/null @@ -1,258 +0,0 @@ -assertInstanceOf($expectedClass, HttpExceptionFactory::build($errorCode)); - } - - public function testBuildFailed() - { - $this->expectException(ValidationException::class); - HttpExceptionFactory::build(101); - } - - /** - * @dataProvider dataProvider - * @param int $errorCode - * @param string $expectedClass - */ - public function testBuildWithContext(int $errorCode, string $expectedClass) - { - $ctx = new stdClass(); - $message = 'test'; - $previousException = new \Exception(); - $exception = HttpExceptionFactory::buildWithContext($errorCode, $ctx, $message, $previousException); - $this->assertInstanceOf($expectedClass, $exception); - $this->assertSame($ctx, $exception->getContext()); - $this->assertSame('test', $exception->getMessage()); - $this->assertSame($previousException, $exception->getPrevious()); - } - - public function testBuildWithContextFailed() - { - $this->expectException(ValidationException::class); - HttpExceptionFactory::buildWithContext(101, []); - } - - public function testExtendingHelper() - { - $helper = new class extends HttpExceptionFactory { - protected static function getMapping(): array - { - return [ - 101 => CustomHttpException::class - ]; - } - }; - - $exception = $helper::build(101); - $this->assertInstanceOf(CustomHttpException::class, $exception); - } - - public function dataProvider() - { - yield 'Client\BadRequestException' => [ - 'errorCode' => 400, - 'expectedClass' => Client\BadRequestException::class, - ]; - - yield 'Client\UnauthorizedException' => [ - 'errorCode' => 401, - 'expectedClass' => Client\UnauthorizedException::class, - ]; - - yield 'Client\PaymentRequiredException' => [ - 'errorCode' => 402, - 'expectedClass' => Client\PaymentRequiredException::class, - ]; - - yield 'Client\ForbiddenException' => [ - 'errorCode' => 403, - 'expectedClass' => Client\ForbiddenException::class, - ]; - - yield 'Client\NotFoundException' => [ - 'errorCode' => 404, - 'expectedClass' => Client\NotFoundException::class, - ]; - - yield 'Client\MethodNotAllowedException' => [ - 'errorCode' => 405, - 'expectedClass' => Client\MethodNotAllowedException::class, - ]; - - yield 'Client\NotAcceptableException' => [ - 'errorCode' => 406, - 'expectedClass' => Client\NotAcceptableException::class, - ]; - - yield 'Client\ProxyAuthorizationRequiredException' => [ - 'errorCode' => 407, - 'expectedClass' => Client\ProxyAuthorizationRequiredException::class, - ]; - - yield 'Clxient\RequestTimeoutException' => [ - 'errorCode' => 408, - 'expectedClass' => Client\RequestTimeoutException::class, - ]; - - yield 'Client\ConflictException' => [ - 'errorCode' => 409, - 'expectedClass' => Client\ConflictException::class, - ]; - - yield 'Client\GoneException' => [ - 'errorCode' => 410, - 'expectedClass' => Client\GoneException::class, - ]; - - yield 'Client\LengthRequiredException' => [ - 'errorCode' => 411, - 'expectedClass' => Client\LengthRequiredException::class, - ]; - - yield 'Client\PreConditionRequiredException' => [ - 'errorCode' => 412, - 'expectedClass' => Client\PreConditionRequiredException::class, - ]; - - yield 'Client\PayloadTooLargeException' => [ - 'errorCode' => 413, - 'expectedClass' => Client\PayloadTooLargeException::class, - ]; - - yield 'Client\URITooLongException' => [ - 'errorCode' => 414, - 'expectedClass' => Client\URITooLongException::class, - ]; - - yield 'Client\UnsupportedMediaTypeException' => [ - 'errorCode' => 415, - 'expectedClass' => Client\UnsupportedMediaTypeException::class, - ]; - - yield 'Client\RangeNotSatisfiableException' => [ - 'errorCode' => 416, - 'expectedClass' => Client\RangeNotSatisfiableException::class, - ]; - - yield 'Client\ExpectationFailedException' => [ - 'errorCode' => 417, - 'expectedClass' => Client\ExpectationFailedException::class, - ]; - - yield 'Client\ImATeapotException' => [ - 'errorCode' => 418, - 'expectedClass' => Client\ImATeapotException::class, - ]; - - yield 'Client\MisdirectedRequestException' => [ - 'errorCode' => 421, - 'expectedClass' => Client\MisdirectedRequestException::class, - ]; - - yield 'Client\UnprocessableEntityException' => [ - 'errorCode' => 422, - 'expectedClass' => Client\UnprocessableEntityException::class, - ]; - - yield 'Client\LockedException' => [ - 'errorCode' => 423, - 'expectedClass' => Client\LockedException::class, - ]; - - yield 'Client\FailedDependencyException' => [ - 'errorCode' => 424, - 'expectedClass' => Client\FailedDependencyException::class, - ]; - - yield 'Client\UpgradeRequiredException' => [ - 'errorCode' => 426, - 'expectedClass' => Client\UpgradeRequiredException::class, - ]; - - yield 'Client\PreConditionRequiredException' => [ - 'errorCode' => 428, - 'expectedClass' => Client\PreConditionRequiredException::class, - ]; - - yield 'Client\TooManyRequestsException' => [ - 'errorCode' => 429, - 'expectedClass' => Client\TooManyRequestsException::class, - ]; - - yield 'Client\RequestHeaderFieldsTooLargeException' => [ - 'errorCode' => 431, - 'expectedClass' => Client\RequestHeaderFieldsTooLargeException::class, - ]; - - yield 'Client\UnavailableForLegalReasonsException' => [ - 'errorCode' => 451, - 'expectedClass' => Client\UnavailableForLegalReasonsException::class, - ]; - - yield 'Client\UnrecoverableErrorException' => [ - 'errorCode' => 456, - 'expectedClass' => Client\UnrecoverableErrorException::class, - ]; - - yield 'Server\InternalServerErrorException' => [ - 'errorCode' => 500, - 'expectedClass' => Server\InternalServerErrorException::class, - ]; - - yield 'Server\NotImplementedException' => [ - 'errorCode' => 501, - 'expectedClass' => Server\NotImplementedException::class, - ]; - - yield 'Server\BadGatewayException' => [ - 'errorCode' => 502, - 'expectedClass' => Server\BadGatewayException::class, - ]; - - yield 'Server\ServiceUnavailableException' => [ - 'errorCode' => 503, - 'expectedClass' => Server\ServiceUnavailableException::class, - ]; - - yield 'Server\GatewayTimeoutException' => [ - 'errorCode' => 504, - 'expectedClass' => Server\GatewayTimeoutException::class, - ]; - - yield 'Server\HttpVersionNotSupportedException' => [ - 'errorCode' => 505, - 'expectedClass' => Server\HttpVersionNotSupportedException::class, - ]; - - yield 'Server\InsuficientStorageException' => [ - 'errorCode' => 507, - 'expectedClass' => Server\InsuficientStorageException::class, - ]; - - yield 'Server\LoopDetectedException' => [ - 'errorCode' => 508, - 'expectedClass' => Server\LoopDetectedException::class, - ]; - } -} diff --git a/Tests/VarianceTest.php b/Tests/VarianceTest.php deleted file mode 100644 index b37a74f..0000000 --- a/Tests/VarianceTest.php +++ /dev/null @@ -1,128 +0,0 @@ -assertTrue(true); - } - - try { - throw new Data\NotFoundException(); - } catch (Tag\NotFoundTag $ex) { - $this->assertTrue(true); - } - - // Ensure NotImplementedException is still catchable by old OperationAbortedException tag and new AbortedTag - try { - throw new Operation\NotImplementedException(); - } catch (Tag\OperationAbortedException $ex) { - $this->assertTrue(true); - } - - try { - throw new Operation\NotImplementedException(); - } catch (Tag\AbortedTag $ex) { - $this->assertTrue(true); - } - - // Ensure KeyAlreadyExistsException is still catchable by old AlreadyExistsException tag and new ExistsTag - try { - throw new Collection\KeyAlreadyExistsException(); - } catch (Tag\AlreadyExistsException $ex) { - $this->assertTrue(true); - } - - try { - throw new Collection\KeyAlreadyExistsException(); - } catch (Tag\ExistsTag $ex) { - $this->assertTrue(true); - } - - // Ensure IntegrityException is still catchable by old InvalidDataException tag and new InvalidDataTag - try { - throw new Data\IntegrityException(); - } catch (Tag\InvalidDataException $ex) { - $this->assertTrue(true); - } - - try { - throw new Data\IntegrityException(); - } catch (Tag\InvalidDataTag $ex) { - $this->assertTrue(true); - } - } - - /** - * Ensures that you can catch the new exception with the old exception - */ - public function testCovarianceReplacedExceptionCatching() - { - try { - throw new Http\Client\RangeNotSatisfiableException(); - } catch (Http\Client\RequestedRangeNotSatisfiableException $ex) { - $this->assertTrue(true); - } - - try { - throw new Http\Client\PayloadTooLargeException(); - } catch (Http\Client\RequestEntityTooLargeException$ex) { - $this->assertTrue(true); - } - - try { - throw new Http\Client\RangeNotSatisfiableException(); - } catch (Http\Client\RequestedRangeNotSatisfiableException $ex) { - $this->assertTrue(true); - } - - try { - throw new Http\Client\PayloadTooLargeException(); - } catch (Http\Client\RequestEntityTooLargeException $ex) { - $this->assertTrue(true); - } - } - - /** - * Ensures that you cannot catch the old exception with the new exception - * - * @expectedException \Exceptions\Http\Client\RequestedRangeNotSatisfiableException - */ - public function testContravarianceReplacedExceptionCatchingShouldFail1() - { - try { - throw new Http\Client\RequestedRangeNotSatisfiableException(); - } catch (Http\Client\RangeNotSatisfiableException $ex) { - } - } - - /** - * Ensures that you cannot catch the old exception with the new exception - * - * @expectedException \Exceptions\Http\Client\RequestEntityTooLargeException - */ - public function testContravarianceReplacedExceptionCatchingShouldFail2() - { - try { - throw new Http\Client\RequestEntityTooLargeException(); - } catch (Http\Client\PayloadTooLargeException $ex) { - } - } -} diff --git a/Tests/stub/CustomHttpException.php b/Tests/stub/CustomHttpException.php deleted file mode 100644 index c41d3c1..0000000 --- a/Tests/stub/CustomHttpException.php +++ /dev/null @@ -1,28 +0,0 @@ -=7.1" - }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.15", - "phpunit/phpunit": "^7.1" + "friendsofphp/php-cs-fixer": "*" }, "config": { "sort-packages": true, "optimize-autoloader": true }, "scripts": { - "test": "vendor/bin/phpunit", "lint": [ "vendor/bin/php-cs-fixer --diff --dry-run -v fix Exceptions", - "vendor/bin/php-cs-fixer --diff --dry-run -v fix Helpers", - "vendor/bin/php-cs-fixer --diff --dry-run -v fix Tests" + "vendor/bin/php-cs-fixer --diff --dry-run -v fix Helpers" ], "fix": [ "vendor/bin/php-cs-fixer --diff -v fix Exceptions", - "vendor/bin/php-cs-fixer --diff -v fix Helpers", - "vendor/bin/php-cs-fixer --diff -v fix Tests" + "vendor/bin/php-cs-fixer --diff -v fix Helpers" ] } } diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..f26b407 --- /dev/null +++ b/composer.lock @@ -0,0 +1,2550 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "9cc61f4a7268aa49f96d8f1207e3b0d8", + "packages": [], + "packages-dev": [ + { + "name": "clue/ndjson-react", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/clue/reactphp-ndjson.git", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", + "shasum": "" + }, + "require": { + "php": ">=5.3", + "react/stream": "^1.2" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", + "react/event-loop": "^1.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Clue\\React\\NDJson\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", + "homepage": "https://github.com/clue/reactphp-ndjson", + "keywords": [ + "NDJSON", + "json", + "jsonlines", + "newline", + "reactphp", + "streaming" + ], + "support": { + "issues": "https://github.com/clue/reactphp-ndjson/issues", + "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-12-23T10:58:28+00:00" + }, + { + "name": "composer/pcre", + "version": "3.3.1", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/63aaeac21d7e775ff9bc9d45021e1745c97521c4", + "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.11.10", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.1" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-08-27T18:44:43+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.3", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.3" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-09-19T14:15:21+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-05-06T16:37:16+00:00" + }, + { + "name": "evenement/evenement", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/igorw/evenement.git", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9 || ^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Evenement\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "description": "Événement is a very simple event dispatching library for PHP", + "keywords": [ + "event-dispatcher", + "event-emitter" + ], + "support": { + "issues": "https://github.com/igorw/evenement/issues", + "source": "https://github.com/igorw/evenement/tree/v3.0.2" + }, + "time": "2023-08-08T05:53:35+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "8520451a140d3f46ac33042715115e290cf5785f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", + "reference": "8520451a140d3f46ac33042715115e290cf5785f", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.2", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.2.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2024-08-06T10:04:20+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.64.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "58dd9c931c785a79739310aef5178928305ffa67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/58dd9c931c785a79739310aef5178928305ffa67", + "reference": "58dd9c931c785a79739310aef5178928305ffa67", + "shasum": "" + }, + "require": { + "clue/ndjson-react": "^1.0", + "composer/semver": "^3.4", + "composer/xdebug-handler": "^3.0.3", + "ext-filter": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "fidry/cpu-core-counter": "^1.0", + "php": "^7.4 || ^8.0", + "react/child-process": "^0.6.5", + "react/event-loop": "^1.0", + "react/promise": "^2.0 || ^3.0", + "react/socket": "^1.0", + "react/stream": "^1.0", + "sebastian/diff": "^4.0 || ^5.0 || ^6.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", + "symfony/finder": "^5.4 || ^6.0 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", + "symfony/polyfill-mbstring": "^1.28", + "symfony/polyfill-php80": "^1.28", + "symfony/polyfill-php81": "^1.28", + "symfony/process": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" + }, + "require-dev": { + "facile-it/paraunit": "^1.3 || ^2.3", + "infection/infection": "^0.29.5", + "justinrainbow/json-schema": "^5.2", + "keradus/cli-executor": "^2.1", + "mikey179/vfsstream": "^1.6.11", + "php-coveralls/php-coveralls": "^2.7", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.5", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.5", + "phpunit/phpunit": "^9.6.19 || ^10.5.21 || ^11.2", + "symfony/var-dumper": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "exclude-from-classmap": [ + "src/Fixer/Internal/*" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.64.0" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2024-08-30T23:09:38+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "react/cache", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/cache.git", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/promise": "^3.0 || ^2.0 || ^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, Promise-based cache interface for ReactPHP", + "keywords": [ + "cache", + "caching", + "promise", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/cache/issues", + "source": "https://github.com/reactphp/cache/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2022-11-30T15:59:55+00:00" + }, + { + "name": "react/child-process", + "version": "v0.6.5", + "source": { + "type": "git", + "url": "https://github.com/reactphp/child-process.git", + "reference": "e71eb1aa55f057c7a4a0d08d06b0b0a484bead43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/e71eb1aa55f057c7a4a0d08d06b0b0a484bead43", + "reference": "e71eb1aa55f057c7a4a0d08d06b0b0a484bead43", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/event-loop": "^1.2", + "react/stream": "^1.2" + }, + "require-dev": { + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35", + "react/socket": "^1.8", + "sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\ChildProcess\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven library for executing child processes with ReactPHP.", + "keywords": [ + "event-driven", + "process", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/child-process/issues", + "source": "https://github.com/reactphp/child-process/tree/v0.6.5" + }, + "funding": [ + { + "url": "https://github.com/WyriHaximus", + "type": "github" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-09-16T13:41:56+00:00" + }, + { + "name": "react/dns", + "version": "v1.13.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/dns.git", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/cache": "^1.0 || ^0.6 || ^0.5", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.7 || ^1.2.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3 || ^2", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Dns\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async DNS resolver for ReactPHP", + "keywords": [ + "async", + "dns", + "dns-resolver", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/dns/issues", + "source": "https://github.com/reactphp/dns/tree/v1.13.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-13T14:18:03+00:00" + }, + { + "name": "react/event-loop", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/event-loop.git", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "suggest": { + "ext-pcntl": "For signal handling support when using the StreamSelectLoop" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\EventLoop\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", + "keywords": [ + "asynchronous", + "event-loop" + ], + "support": { + "issues": "https://github.com/reactphp/event-loop/issues", + "source": "https://github.com/reactphp/event-loop/tree/v1.5.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2023-11-13T13:48:05+00:00" + }, + { + "name": "react/promise", + "version": "v3.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/8a164643313c71354582dc850b42b33fa12a4b63", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63", + "shasum": "" + }, + "require": { + "php": ">=7.1.0" + }, + "require-dev": { + "phpstan/phpstan": "1.10.39 || 1.4.10", + "phpunit/phpunit": "^9.6 || ^7.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "React\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "support": { + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v3.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-05-24T10:39:05+00:00" + }, + { + "name": "react/socket", + "version": "v1.16.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/socket.git", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/dns": "^1.13", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.6 || ^1.2.1", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3.3 || ^2", + "react/promise-stream": "^1.4", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Socket\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", + "keywords": [ + "Connection", + "Socket", + "async", + "reactphp", + "stream" + ], + "support": { + "issues": "https://github.com/reactphp/socket/issues", + "source": "https://github.com/reactphp/socket/tree/v1.16.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-07-26T10:38:09+00:00" + }, + { + "name": "react/stream", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/stream.git", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.8", + "react/event-loop": "^1.2" + }, + "require-dev": { + "clue/stream-filter": "~1.2", + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", + "keywords": [ + "event-driven", + "io", + "non-blocking", + "pipe", + "reactphp", + "readable", + "stream", + "writable" + ], + "support": { + "issues": "https://github.com/reactphp/stream/issues", + "source": "https://github.com/reactphp/stream/tree/v1.4.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-11T12:45:25+00:00" + }, + { + "name": "sebastian/diff", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:53:05+00:00" + }, + { + "name": "symfony/console", + "version": "v7.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/0fa539d12b3ccf068a722bbbffa07ca7079af9ee", + "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^6.4|^7.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v7.1.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-20T08:28:38+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7", + "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v7.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-05-31T14:57:53+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v7.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/61fe0566189bf32e8cfee78335d8776f64a66f5a", + "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v7.1.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-17T09:16:35+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.1.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "d95bbf319f7d052082fb7af147e0f835a695e823" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823", + "reference": "d95bbf319f7d052082fb7af147e0f835a695e823", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v7.1.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-08-13T14:28:19+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v7.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/47aa818121ed3950acd2b58d1d37d08a94f9bf55", + "reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v7.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-05-31T14:57:53+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/process", + "version": "v7.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "5c03ee6369281177f07f7c68252a280beccba847" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/5c03ee6369281177f07f7c68252a280beccba847", + "reference": "5c03ee6369281177f07f7c68252a280beccba847", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v7.1.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-19T21:48:23+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v7.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d", + "reference": "5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v7.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-05-31T14:57:53+00:00" + }, + { + "name": "symfony/string", + "version": "v7.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/d66f9c343fa894ec2037cc928381df90a7ad4306", + "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/emoji": "^7.1", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v7.1.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-20T08:28:38+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/docs/contribute.md b/docs/contribute.md index 4f6d71f..bd7b467 100644 --- a/docs/contribute.md +++ b/docs/contribute.md @@ -19,27 +19,17 @@ You can also code your contribution away if you have the skills. It isn't all th There are some restrictions though! ## Restrictions - -* You must write a test for anything you add or change in terms of feature: - - * `FeatureTest.php` should contain a test about your changes. - * `DependencyTest.php` should be updated with any new exception to ensure that further changes down the road don't break anything. - * `VarianceTest.php` should be updated if you create any new tags or exceptions that replace another one so that you can prove you are not breaking any old code through covariant or contravariant changes. * Your code must be documented: - * In the docs. * In the code files. * Your code must be clean and well formatted: - * You can run `composer run lint` to see what is not well formatted. * You can run `composer run fix` to fix all linting errors. - -* All tests must pass, you can run `composer run test` on your machine before hand. ## Approval process * We will look at the changes and ask for changes directly on the PR. * Please read the PR template properly beforehand as it contains all information posted here regarding the restrictions. -* We reserve the right to refuse any modification but we will gladly incorporate well thought changes proposed to us. \ No newline at end of file +* We reserve the right to refuse any modification, but we will gladly incorporate well thought changes proposed to us. diff --git a/docs/exceptions/collection-exceptions.md b/docs/exceptions/collection-exceptions.md index ef06996..c546661 100644 --- a/docs/exceptions/collection-exceptions.md +++ b/docs/exceptions/collection-exceptions.md @@ -27,7 +27,7 @@ Tags: None ### FullException -Use this exception when an operation on a collection cannot be achieved because the collection has already reached it's limit and cannot accept more data. +Use this exception when an operation on a collection cannot be achieved because the collection has already reached its limit and cannot accept more data. Tags: None @@ -55,4 +55,4 @@ Tags: None Use this exception when an operation on a collection item that is locked/read-only tries to modify the item in question. -Tags: None \ No newline at end of file +Tags: None diff --git a/docs/exceptions/data-exceptions.md b/docs/exceptions/data-exceptions.md index 3d0dfb9..18f5909 100644 --- a/docs/exceptions/data-exceptions.md +++ b/docs/exceptions/data-exceptions.md @@ -1,6 +1,6 @@ # Data exceptions -Data exceptions pertain to all the validation aspect of data and the operations associated to it. They are not stored as `Validation\` exceptions because they do not pertain to validation frameworks but to the integrity and validity of the data itself not to it's validation. +Data exceptions pertain to all the validation aspect of data and the operations associated to it. They are not stored as `Validation\` exceptions because they do not pertain to validation frameworks but to the integrity and validity of the data itself not to its validation. ## Classes @@ -31,7 +31,7 @@ Tags: `\Exception\Tag\InvalidDataTag` ### FoundTooLittleException -Use this exception when the data requested by your code was found but it found actually less than expected. A good use for this is when you are looking for a specific set of items such as 10 items but you end up finding only 9. In this case, you throw this exception. +Use this exception when the data requested by your code was found, but it found actually less than expected. A good use for this is when you are looking for a specific set of items such as 10 items, but you end up finding only 9. In this case, you throw this exception. > **IMPORTANT NOTE**: If the code in context is a service provider that queries a database, this would be the right exception to throw and listen for. The controller on the other hand would catch this and throw a NotFoundException from the Http namespace which would be converted to a standardized message in the front controller. @@ -39,7 +39,7 @@ Tags: None ### FoundTooManyException -Use this exception when the data requested by your code was found and it found actually more than expected. A good use for this is the findSingle usual function we find in many library and orm. If you have more than 1 record found, it might mean that you should send back this exception. +Use this exception when the data requested by your code was found, and it found actually more than expected. A good use for this is the findSingle usual function we find in many library and orm. If you have more than 1 record found, it might mean that you should send back this exception. > **IMPORTANT NOTE**: If the code in context is a service provider that queries a database, this would be the right exception to throw and listen for. The controller on the other hand would catch this and throw a NotFoundException from the Http namespace which would be converted to a standardized message in the front controller. @@ -73,4 +73,4 @@ The data provided to your code is not following expected validations. These vali > **IMPORTANT NOTE**: Although debatable, you should note that an integrity exception should be the one being thrown when the validation goes further down the chain into the business systems. `ValidationException` should be sent back if the basic format of data, data types or basic scalar constraints are not met. -Tags: `\Exceptions\Tag\InvalidDataTag` \ No newline at end of file +Tags: `\Exceptions\Tag\InvalidDataTag` diff --git a/docs/exceptions/http-client-exceptions.md b/docs/exceptions/http-client-exceptions.md index 6391144..7b516e8 100644 --- a/docs/exceptions/http-client-exceptions.md +++ b/docs/exceptions/http-client-exceptions.md @@ -1,17 +1,16 @@ # Http client exceptions -Many frameworks and applications redefine Http exceptions that map to Http status codes. These should not be redefined or they become different across two projects and portability of your code suffers. This namespace contains most if not all Http exceptions you'll ever need. +Many frameworks and applications redefine Http exceptions that map to Http status codes. These should not be redefined, or they become different across two projects and portability of your code suffers. This namespace contains most if not all Http exceptions you'll ever need. This document details client http exception or the class of http responses that map to the 400s response code. -> **GENERAL IMPORTANT NOTE REGARDING HTTP EXCEPTIONS**: Never throw an exception at the user. Always catch it and synthesize it to a correct html response with -appropriate headers. You can use the constants and accessor to get HTML values to return. +> **GENERAL IMPORTANT NOTE REGARDING HTTP EXCEPTIONS**: Never throw an exception at the user. Always catch it and synthesize it to a correct html response with appropriate headers. You can use the constants and accessor to get HTML values to return. ## Classes Namespaces: `\Exceptions\Http` and `\Exceptions\Http\Client` -Base classs: `\Exceptions\Http\HttpException` and `\Exceptions\Http\Client\ClientErrorException` +Base classes: `\Exceptions\Http\HttpException` and `\Exceptions\Http\Client\ClientErrorException` Base interfaces: `\Exceptions\Http\HttpExceptionInterface` and `\Exceptions\Http\Client\ClientErrorExceptionInterface` @@ -32,12 +31,11 @@ Exceptions: * 410: GoneException * 411: LengthRequiredException * 412: PreConditionFailedException -* 413: PayloadTooLargeException (Replaces `RequestEntityTooLargeException`) +* 413: PayloadTooLargeException * 414: URITooLongException * 415: UnsupportedMediaTypeException -* 416: RangeNotSatisfiableException (Replaces `RequestedRangeNotSatisfiableException`) +* 416: RangeNotSatisfiableException * 417: ExpectationFailedException -* 418: ImATeapotException * 421: MisdirectedRequestException * 422: UnprocessableEntityException * 423: LockedException @@ -53,7 +51,7 @@ Exceptions: You should use this exception when the request just couldn't be understood at all. This can be used for various reasons such as the request not following the expected structure like form encoding or raw JSON in the body or maybe the information in the body was supposed to be encrypted and it was not. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` +Tags: `\Exceptions\Tag\InvalidDataTag` --- @@ -63,17 +61,17 @@ You should use this exception when the request is not providing identification m > **DEBATABLE**: if a user does not have permission to do something, you should be sending back a ForbiddenException instead of a UnauthorizedException. The user at this point is identified so not having the rights to do something should not require the user to change credentials because it would then be a different user. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\UnauthorizedTag` +Tags: `\Exceptions\Tag\UnauthorizedTag` --- ### 402: PaymentRequiredException -You should use this exception when the user would have access to a certain resource if he had payed for the feature or content. +You should use this exception when the user would have access to a certain resource if he had paid for the feature or content. -> **IMPORTANT NOTE**: This is a reserved status code in HTTP 1.1 standard but it was never finalized or integrated. Use this at your own risk. We suggest you use the ForbiddenException instead, it has a wider meaning but at least it is an official status code. +> **IMPORTANT NOTE**: This is a reserved status code in HTTP 1.1 standard, but it was never finalized or integrated. Use this at your own risk. We suggest you use the ForbiddenException instead, it has a wider meaning but at least it is an official status code. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\ForbiddenTag` +Tags: `\Exceptions\Tag\ForbiddenTag` --- @@ -83,7 +81,7 @@ You should use this exception only when the operation attempted by the request w > **DEBATABLE**: If a user does not have permission to do something, you should be sending back a ForbiddenException but if the user does not have access to the resource because it is not owned by the current user or shared with the current user then you should probably send back a NotFoundException instead for security reasons. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\ForbiddenTag` +Tags: `\Exceptions\Tag\ForbiddenTag` --- @@ -93,7 +91,7 @@ You should use this exception when a request cannot reach or find the requested > **DEBATABLE**: If a user does not have permission to do something, you should be sending back a ForbiddenException but if the user does not have access to the resource because it is not owned by the current user or shared with the current user then you should probably send back a NotFoundException instead for security reasons. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\NotFoundTag` +Tags: `\Exceptions\Tag\NotFoundTag` --- @@ -101,7 +99,7 @@ Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\NotFoundTag` You should use this exception when a request features a method (GET, PUT, POST, CUSTOM) that is not applicable to the resource being manipulated/requested. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` +Tags: `\Exceptions\Tag\InvalidDataTag` --- @@ -109,7 +107,7 @@ Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` You should use this exception when a request features an acceptance criteria that the server cannot respond to. For example, your user asks for an ACCEPT-LANGUAGE that you do not support. This response type applies to any type of accept requirement passed on by the user to the server. Any accept header value that your server cannot support, you should throw this exception back. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` +Tags: `\Exceptions\Tag\InvalidDataTag` --- @@ -121,7 +119,7 @@ When an additional request needs to pass through a proxy server but the credenti If the user sends the same request again, the same error should occur. Unless the proxy is updated, the credentials are added or changed, this request should not succeed. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\UnauthorizedTag` +Tags: `\Exceptions\Tag\UnauthorizedTag` --- @@ -129,13 +127,11 @@ Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\UnauthorizedTag` > You should use this exception only when the request being passed on to your server requires a sub-process to go through another distant server. -When an additional request needs to go to a distant server but the response never comes back and you get a timeout, this is the exception you should throw back at your user. +When an additional request needs to go to a distant server but the response never comes back, and you get a timeout, this is the exception you should throw back at your user. If the user sends the same request again, the error may or may not occur again depending on the reason why the request timed out in the first place. -> **DEBATABLE**: If the request you are responding to does not require a distant call to another server but has a long standing sub process on the same machine that fails to respond in time, you should probably use the OperationTimedOutException instead of the RequestTimeoutException. - -Tags: `\Exceptions\Tag\AbortedTag` +> **DEBATABLE**: If the request you are responding to does not require a distant call to another server but has a long-standing sub process on the same machine that fails to respond in time, you should probably use the OperationTimedOutException instead of the RequestTimeoutException. --- @@ -145,17 +141,17 @@ You should use this exception when the request features an operation that would A common use case for this exception would be for insertions or updates on a database that would trigger a unique constraint to fail validation. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` +Tags: `\Exceptions\Tag\InvalidDataTag` --- ### 410: GoneException -You should use this exception when the state of a resource makes the resource unavailable due to state transition such as when a soft delete operation is executed on it. The resource is still there but it is gone because it has been deleted. +You should use this exception when the state of a resource makes the resource unavailable due to state transition such as when a soft delete operation is executed on it. The resource is still there, but it is gone because it has been deleted. -> **DEBATABLE**: A lot of products out there will return a Not found (404) when a resource is not available. It is a more common practice. You may want to validate the impacts of using a 410 Gone as a response to content that was soft deleted. +> **DEBATABLE**: A lot of products out there will return a Not found (404) when a resource is not available. It is a more common practice. You may want to validate the impacts of using a 410 Gone as a response to content that was softly deleted. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\NotFoundTag` +Tags: `\Exceptions\Tag\NotFoundTag` --- @@ -167,7 +163,7 @@ You should use this exception when the request made towards are resource does no This is usually only used in a stream supported request context as a PHP server should never get a partial request. You may however need to handle/throw this exception if you do a distant request that does not satisfy this condition. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` +Tags: `\Exceptions\Tag\InvalidDataTag` --- @@ -175,7 +171,7 @@ Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` You should use this exception when the request made towards a resource is supporting one or more pre-condition HTTP headers and one of those headers cannot be met due to an invalid value or due to an invalid header name. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` +Tags: `\Exceptions\Tag\InvalidDataTag` --- @@ -185,11 +181,9 @@ Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` You should use this exception only when you receive the same response from a distant server that refuses to process your request because the payload/content body that you send exceeds the server's limitations. -This is usually not used in a PHP context because your server such as Nginx or Apache will refuse the request before you. It is possible for you to read the request body and decide that the request is too big but it is an improbable scenario. - -Replaces `RequestEntityTooLargeException` +This is usually not used in a PHP context because your server such as Nginx or Apache will refuse the request before you. It is possible for you to read the request body and decide that the request is too big, but it is an improbable scenario. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` +Tags: `\Exceptions\Tag\InvalidDataTag` --- @@ -197,31 +191,29 @@ Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` > You should use this exception only when the request being passed on to your server requires a sub-process to go through another distant server. -You should use this exception only when you receive the same response from a distant server that refuses to process your request because the request URI you requested contained too much information and it exceeded the server's limitations. +You should use this exception only when you receive the same response from a distant server that refuses to process your request because the request URI you requested contained too much information, and it exceeded the server's limitations. -This is usually not used in a PHP context because your server such as Nginx or Apache will refuse the request before you. It is possible for you to read the request URI and decide that the request URI is too big but it is an improbable scenario. +This is usually not used in a PHP context because your server such as Nginx or Apache will refuse the request before you. It is possible for you to read the request URI and decide that the request URI is too big, but it is an improbable scenario. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` +Tags: `\Exceptions\Tag\InvalidDataTag` --- ### 415: UnsupportedMediaTypeException -You should use this exception when a request features an expected response type that the server cannot respond to. For example, your user asks for an ACCEPT content-type that you do not support such as `application/pdf` and the resource cannnot be converted to such a media type. On the opposite of `NotAcceptableException`, this exception applies only to the ACCEPT header that specifies the media type the user is expecting. +You should use this exception when a request features an expected response type that the server cannot respond to. For example, your user asks for an ACCEPT content-type that you do not support such as `application/pdf` and the resource cannot be converted to such a media type. On the opposite of `NotAcceptableException`, this exception applies only to the ACCEPT header that specifies the media type the user is expecting. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` +Tags: `\Exceptions\Tag\InvalidDataTag` --- ### 416: RangeNotSatisfiableException -When a request is made and it contains a range specification, you should validate that the range can indeed be fulfilled properly. If the range cannot be fulfilled properly, you should return this response. +When a request is made, and it contains a range specification, you should validate that the range can indeed be fulfilled properly. If the range cannot be fulfilled properly, you should return this response. > **DEBATABLE**: You could send back this response only if the range is completely off or invalid but still respond to incomplete range requests that fall out of the bound of the result requested for. For example, user asks for records 100-110 but your system only has 107 records, should you return a `RangeNotSatisfiableException` or still serve the request with only 7 results? -Replaces: `RequestedRangeNotSatisfiableException` - -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` +Tags: `\Exceptions\Tag\InvalidDataTag` --- @@ -231,15 +223,7 @@ Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` You should use this exception when the request made towards a resource is supporting the expect HTTP header and the operation cannot be fulfilled properly because the result of the operation does not math the expected result. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` - ---- - -### 418: ImATeapotException - -1998 April's fools joke introduced this status code. We had to integrate it into the library although it is completely useless. Can you find the easter egg regarding this class? - -Tags: `\Exceptions\Tag\AbortedTag` +Tags: `\Exceptions\Tag\InvalidDataTag` --- @@ -247,8 +231,6 @@ Tags: `\Exceptions\Tag\AbortedTag` You should use this exception in the event a request cannot be handled by the current server because, for example, it does not have access to the resources or features necessary to respond to the request. -Tags: `\Exceptions\Tag\AbortedTag` - --- ### 422: UnprocessableEntityException @@ -257,7 +239,7 @@ You should use this exception in the event the data in the request does not pass > **DEBATABLE**: How do you consider a conflict in the database versus an unprocessable entity? If an entity is gone, do you send a 403, a 404, a 409, a 410 or a 422? These are all very subjective choices! We suggest you send a 422 on basic validation rules not passing and a 409 Conflict only if the operation you are running fails to complete due to an integrity issue. It does not mean you cannot validate integrity/uniqueness during the basic validation stage but if you do so, you should always return 422 at that point. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` +Tags: `\Exceptions\Tag\InvalidDataTag` --- @@ -267,25 +249,23 @@ You should use this exception in the event the data being requested is done on a > **IMPORTANT NOTE**: Soft locking or optimistic/pessimistic locked is not a common practice on the web but not impossible. There is a lot of documentation on how to implement locking but no clear way to do it. Use this at your own risk. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\ForbiddenTag` +Tags: `\Exceptions\Tag\ForbiddenTag` --- ### 424: FailedDependencyException -You should use this when an external sub-process required by the request ends up in error and you can't reveal or well define the error back tot he user. This is analogous to the `OperationAbortedException` exception in a sense that an underlying operation failed to complete. - -Tags: `\Exceptions\Tag\AbortedTag` +You should use this when an external sub-process required by the request ends up in error, and you can't reveal or well define the error back to the user. --- ### 426: UpgradeRequiredException -You should use this when the request is not up to date with the communication protocol to use. This should be normally returned by the underlying web server in SSL/TLS incompatibility scenarios but nothing prevents you from using this exception to signal a user that the request he did requires an updated communication protocol or format. +You should use this when the request is not up-to-date with the communication protocol to use. This should be normally returned by the underlying web server in SSL/TLS incompatibility scenarios but nothing prevents you from using this exception to signal a user that the request he did requires an updated communication protocol or format. -> **DEBATABLE**: This is very analogous to the 422 Unprocessable entity and 415 Unsupported Media Type because if you don't have a version specifier with your request, this means the the entity is in fact unprocessable. You'd need a means to identify the version of the request and send back this exception instead of a 422. If the version is specified but the endpoint doesn't support it anymore, it would probably make more sense to return a 415 Unsupported Media Type. +> **DEBATABLE**: This is very analogous to the 422 Unprocessable entity and 415 Unsupported Media Type because if you don't have a version specifier with your request, this means the entity is in fact unprocessable. You'd need a means to identify the version of the request and send back this exception instead of a 422. If the version is specified but the endpoint doesn't support it anymore, it would probably make more sense to return a 415 Unsupported Media Type. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` +Tags: `\Exceptions\Tag\InvalidDataTag` --- @@ -293,7 +273,7 @@ Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` Analogous to the PreConditionFailedException, this exception should be used when the request is missing a required pre-condition. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` +Tags: `\Exceptions\Tag\InvalidDataTag` --- @@ -303,7 +283,7 @@ You should use this when the request when you have implemented some sort of thro > **IMPORTANT NOTE**: A popular type of request throttling approach for APIs is the leaky bucket algorithm. You can find many articles on this on the internet and depending on your framework, you even have pre-existing middle ware or plugins that already exists ready to integrate. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\ForbiddenTag` +Tags: `\Exceptions\Tag\ForbiddenTag` --- @@ -313,9 +293,9 @@ Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\ForbiddenTag` You should use this exception only when you receive the same response from a distant server that refuses to process your request because the headers or one specific header amounts to too much information and exceeds the server's limitations. -This is usually not used in a PHP context because your server such as Nginx or Apache will refuse the request before you. It is possible for you to read the request headers and decide that the request is invalid but it is an improbable scenario. +This is usually not used in a PHP context because your server such as Nginx or Apache will refuse the request before you. It is possible for you to read the request headers and decide that the request is invalid, but it is an improbable scenario. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` +Tags: `\Exceptions\Tag\InvalidDataTag` --- @@ -323,12 +303,10 @@ Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\InvalidDataTag` You should return this exception when there is a legal request deposited against a specific resource that is being requested. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\ForbiddenTag` +Tags: `\Exceptions\Tag\ForbiddenTag` --- ### 456: UnrecoverableErrorException You should return this exception when the server encounters an unrecoverable error with an internal provider. - -Tags: `\Exceptions\Tag\AbortedTag` \ No newline at end of file diff --git a/docs/exceptions/http-server-exceptions.md b/docs/exceptions/http-server-exceptions.md index 77de0ac..8100947 100644 --- a/docs/exceptions/http-server-exceptions.md +++ b/docs/exceptions/http-server-exceptions.md @@ -1,17 +1,16 @@ # Http server exceptions -Many frameworks and applications redefine Http exceptions that map to Http status codes. These should not be redefined or they become different across two projects and portability of your code suffers. This namespace contains most if not all Http exceptions you'll ever need. +Many frameworks and applications redefine Http exceptions that map to Http status codes. These should not be redefined, or they become different across two projects and portability of your code suffers. This namespace contains most if not all Http exceptions you'll ever need. This document details server http exception or the class of http responses that map to the 500s response code. -> **GENERAL IMPORTANT NOTE REGARDING HTTP EXCEPTIONS**: Never throw an exception at the user. Always catch it and synthesize it to a correct html response with -appropriate headers. You can use the constants and accessor to get HTML values to return. +> **GENERAL IMPORTANT NOTE REGARDING HTTP EXCEPTIONS**: Never throw an exception at the user. Always catch it and synthesize it to a correct html response with appropriate headers. You can use the constants and accessor to get HTML values to return. ## Classes Namespaces: `\Exceptions\Http` and `\Exceptions\Http\Server` -Base classs: `\Exceptions\Http\HttpException` and `\Exceptions\Http\Server\ServerErrorException` +Base classes: `\Exceptions\Http\HttpException` and `\Exceptions\Http\Server\ServerErrorException` Base interfaces: `\Exceptions\Http\HttpExceptionInterface` and `\Exceptions\Http\Server\ServerErrorExceptionInterface` @@ -25,7 +24,7 @@ Exceptions: * 503: ServiceUnavailableException * 504: GatewayTimeoutException * 505: HttpVersionNotSupportedException -* 507: InsuficientStorageException +* 507: InsufficientStorageException * 508: LoopDetectedException ### 500: InternalServerErrorException @@ -34,8 +33,6 @@ You should use this exception when the request results in a generic error that i > **IMPORTANT NOTE**: It is a good practice to catch any exception at a low level in a framework, log it and return a generic 500 exception to the user to protect your code, architecture and data. In a development scenario, you should avoid this to benefit as much as possible from stack traces and debugging features offered by your framework but a production scenario should always use this coupled to an error tracker. -Tags: `\Exceptions\Tag\AbortedTag` - --- ### 501: NotImplementedException @@ -44,15 +41,11 @@ This exception should be used only if a feature is incomplete and unusable. > **IMPORTANT NOTE**: Ask yourself if you need to catch and throw this exception. You should never publish a feature that is not implemented although there are all sorts of scenarios and reasons. Use careful judgement! -Tags: `\Exceptions\Tag\AbortedTag` - --- ### 502: BadGatewayException -This exception is used to signal the user that a downstream process returned an unexpected response and you have no clue what to do with that. Provides a little more information than a raw 500 Internal Server Error exception. - -Tags: `\Exceptions\Tag\AbortedTag` +This exception is used to signal the user that a downstream process returned an unexpected response, and you have no clue what to do with that. Provides a little more information than a raw 500 Internal Server Error exception. --- @@ -62,38 +55,28 @@ You should return this exception when your system is currently unavailable eithe > **IMPORTANT NOTE**: This is the normal error code any system will return while they are in maintenance mode and upgrading a database or code. -Tags: `\Exceptions\Tag\AbortedTag` - --- ### 504: GatewayTimeoutException This exception is used to signal the user that a downstream process timed out while waiting for an answer. This is usually the case when your application uses a distant API that is behind a gateway and the API fails to respond in time. For example, a CDN will usually return 504s when you try to access a resource on it and the resource is not available on it and the remote server fails to respond in it. -> **DEBATABLE**: When you issue a downstream request to another server and it fails to respond in time, should you return a 504 or a 408? 408 means the client failed to respond in time but you would never send that, it would be your gateway or your web server such as Nginx or Apache that would do this for you. Use good judgement when selecting the proper response. - -Tags: `\Exceptions\Tag\AbortedTag` +> **DEBATABLE**: When you issue a downstream request to another server, and it fails to respond in time, should you return a 504 or a 408? 408 means the client failed to respond in time, but you would never send that, it would be your gateway or your web server such as Nginx or Apache that would do this for you. Use good judgement when selecting the proper response. --- ### 505: HttpVersionNotSupportedException -This exception is only implemented for distant request support because you would not be the one to return this status code, it would be your web server such as Nginx or Aapache that would return this. - -Tags: `\Exceptions\Tag\AbortedTag` +This exception is only implemented for distant request support because you would not be the one to return this status code, it would be your web server such as Nginx or Apache that would return this. --- -### 507: InsuficientStorageException +### 507: InsufficientStorageException This exception should be returned if you have a very large request to generate and must pre-generate it before streaming it out to the user. If the response exceeds the available server space or if there is a quota that is exceeded, this would be the proper code to return. -Tags: `\Exceptions\Tag\AbortedTag` - --- ### 508: LoopDetectedException -This exception should be used if you detect that a internal/sub process is acting in a loop because of the request configuration. - -Tags: `\Exceptions\Tag\AbortedTag` \ No newline at end of file +This exception should be used if you detect that an internal/sub process is acting in a loop because of the request configuration. diff --git a/docs/exceptions/io-filesystem-exceptions.md b/docs/exceptions/io-filesystem-exceptions.md index 6679b42..d17ebe2 100644 --- a/docs/exceptions/io-filesystem-exceptions.md +++ b/docs/exceptions/io-filesystem-exceptions.md @@ -8,7 +8,7 @@ This document details filesystem IO exceptions such as files not found or disk p Namespaces: `\Exceptions\IO` and `\Exceptions\IO\Filesystem` -Base classs: `\Exceptions\IO\IOException` and `\Exceptions\IO\Filesystem\FilesystemException` +Base classes: `\Exceptions\IO\IOException` and `\Exceptions\IO\Filesystem\FilesystemException` Base interfaces: `\Exceptions\IO\IOExceptionInterface` and `\Exceptions\IO\Filesystem\FilesystemExceptionInterface` @@ -28,7 +28,7 @@ Exceptions: ### DirectoryAlreadyExistsException -Use this exception when your code tries to create a local directory but it already exists. +Use this exception when your code tries to create a local directory, but it already exists. Tags: `\Exceptions\Tag\ExistsTag` @@ -60,7 +60,7 @@ Tags: `\Exceptions\Tag\ForbiddenTag` ### FileAlreadyExistsException -Use this exception when your code tries to create a file but it already exists. +Use this exception when your code tries to create a file, but it already exists. Tags: `\Exceptions\Tag\ExistsTag` @@ -94,8 +94,6 @@ Tags: `\Exceptions\Tag\ForbiddenTag` Use this exception when your code realizes that there is no more space available on the device to write to. -Tags: `\Exceptions\Tag\AbortedTag` - --- ### NotADirectoryException @@ -110,4 +108,4 @@ Tags: `\Exceptions\Tag\InvalidDataTag` Use this exception when your code tries to do something on a file but the passed on item is not a file. -Tags: `\Exceptions\Tag\InvalidDataTag` \ No newline at end of file +Tags: `\Exceptions\Tag\InvalidDataTag` diff --git a/docs/exceptions/io-network-exceptions.md b/docs/exceptions/io-network-exceptions.md index fa180a1..1b8f3ae 100644 --- a/docs/exceptions/io-network-exceptions.md +++ b/docs/exceptions/io-network-exceptions.md @@ -8,7 +8,7 @@ This document details network IO exceptions such as connection lost or connectio Namespaces: `\Exceptions\IO` and `\Exceptions\IO\Network` -Base classs: `\Exceptions\IO\IOException` and `\Exceptions\IO\Network\NetworkException` +Base classes: `\Exceptions\IO\IOException` and `\Exceptions\IO\Network\NetworkException` Base interfaces: `\Exceptions\IO\IOExceptionInterface` and `\Exceptions\IO\Network\NetworkExceptionInterface` @@ -25,8 +25,6 @@ Exceptions: Use this exception when an IO operation that requires a distant connection gets cut off after negotiating connection. -Tags: `\Exceptions\Tag\AbortedTag` - --- ### ConnectionRefusedException @@ -41,16 +39,12 @@ Tags: `\Exceptions\Tag\ForbiddenTag` Use this exception when an IO network connection fails to connect in time. This exception is slightly different from the RequestTimeoutException where it is the request that failed. -Tags: `\Exceptions\Tag\AbortedTag` - --- ### RequestTimeoutException Use this exception when an IO network request fails to respond in time. This exception is slightly different from the ConnectionTimeoutException where it is the connection to the host that failed. -Tags: `\Exceptions\Tag\AbortedTag` - --- ### UnexpectedResponseException @@ -59,12 +53,10 @@ Use this exception when an IO operation based on a communication protocol receiv For example, establishing an FTP connection on a SFTP server will yield unexpected communication dialog. In this event, an UnexpectedResponseException should be thrown. -Tags: `\Exceptions\Tag\AbortedTag` - --- ### UnknownHostException Use this exception when an IO operation tries to reach a remote host that cannot be resolved due to DNS or IP issues. -Tags: `\Exceptions\Tag\NotFoundTag` \ No newline at end of file +Tags: `\Exceptions\Tag\NotFoundTag` diff --git a/docs/exceptions/operation-exceptions.md b/docs/exceptions/operation-exceptions.md index 1cfad64..d9805ad 100644 --- a/docs/exceptions/operation-exceptions.md +++ b/docs/exceptions/operation-exceptions.md @@ -22,7 +22,7 @@ Exceptions: The user trying to execute an operation is not authorized to perform the operation expected. This results in an incomplete operation but not necessarily in a full request authorization denial. This exception is the big brother of the HTTP unauthorized exception. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\UnauthorizedTag` +Tags: `\Exceptions\Tag\UnauthorizedTag` --- @@ -30,13 +30,13 @@ Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\UnauthorizedTag` The user trying to execute an operation is not allowed to perform the operation expected. This results in an incomplete operation but not necessarily in a full request denial. This exception is the big brother of the HTTP forbidden exception. -Tags: `\Exceptions\Tag\AbortedTag` and `\Exceptions\Tag\ForbiddenTag` +Tags: `\Exceptions\Tag\ForbiddenTag` --- ### InvalidOperationException -Use this exception in the event something went wrong with the state of the application and you cannot allow executing this operation because of that state. For example, processing a report with no report specified would yield an exception of type InvalidOperationException or something similar/custom based on it. This whole set of exceptions didn't exist before but should have as many operations can end up being impossible to execute. +Use this exception in the event something went wrong with the state of the application, and you cannot allow executing this operation because of that state. For example, processing a report with no report specified would yield an exception of type InvalidOperationException or something similar/custom based on it. This whole set of exceptions didn't exist before but should have as many operations can end up being impossible to execute. Tags: `\Exceptions\Tag\InvalidDataTag` @@ -46,12 +46,8 @@ Tags: `\Exceptions\Tag\InvalidDataTag` Use this exception when someone is calling a function/method that is not implemented yet. This is a good practice when implementing a lot of new functionality. Coupled to unit tests, you should not miss a NotImplementedException but at least the message is more verbose. -Tags: `\Exceptions\Tag\AbortedTag` - --- ### UnexpectedException -Use this exception in the event that an operation that expected a certain result from a sub function/method call but did not get what i expected. This exception is the reversed validation exception. Instead of validating the user's input to a function, it is a means to signal that something went wrong when calling a sub components and the result is unexpected. - -Tags: `\Exceptions\Tag\AbortedTag` \ No newline at end of file +Use this exception in the event that an operation that expected a certain result from a sub function/method call but did not get what I expected. This exception is the reversed validation exception. Instead of validating the user's input to a function, it is a means to signal that something went wrong when calling a subcomponents and the result is unexpected. diff --git a/docs/getting-started.md b/docs/getting-started.md index c625e1a..7b65258 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -17,7 +17,7 @@ Or catch them: ```php try { -} catch(\Exceptions\Data\NotFoundExceptions $ex){ +} catch(\Exceptions\Data\NotFoundException $ex){ } ``` @@ -32,15 +32,15 @@ try { } ``` -It is that easy! +It's that easy! Read on in [Usage patterns](patterns.md). # Digging deeper ## New exceptions and namespaces -There are many missing runtime exceptions in the default SPL package. There are many exceptions that we often see re-created over and over again across projects and packages and it does not make sense to do that. +There are many missing runtime exceptions in the default SPL package. There are many exceptions that we often see re-created over and over again across projects and packages, and it does not make sense to do that. -The Standard Exceptions package is all about fixing this. It creates a completely new namespace structure that contains all the exceptions you should need (We sure hope so) and adds several if not many new exceptions so you don't have the define yourself. +The Standard Exceptions package is all about fixing this. It creates a completely new namespace structure that contains all the exceptions you should need (We sure hope so) and adds several if not many new exceptions, so you don't have to define yourself. ## New namespace structure @@ -66,13 +66,13 @@ There are many array/collection based operations out there, collections classes, ### Data exceptions -Data exceptions pertain to all the validation aspect of data and the operations associated to it. They are not stored as `Validation\` exceptions because they do not pertain to validation frameworks but to the integrity and validity of the data itself not to it's validation. +Data exceptions pertain to all the validation aspect of data and the operations associated to it. They are not stored as `Validation\` exceptions because they do not pertain to validation frameworks but to the integrity and validity of the data itself not to its validation. [Learn more](exceptions/data-exceptions.md) ### Http exceptions -Many frameworks and applications redefine Http exceptions that map to Http status codes. These should not be redefined or they become different across two projects and portability of your code suffers. This namespace contains most if not all Http exceptions you'll ever need. +Many frameworks and applications redefine Http exceptions that map to Http status codes. These should not be redefined, or they become different across two projects and portability of your code suffers. This namespace contains most if not all Http exceptions you'll ever need. You will find two sub namespaces in this namespace namely: @@ -112,11 +112,3 @@ These all mean the same thing! You tried to do something on a resource but the u The `Tag\` namespace contains different interfaces that help you convey the same means to your exceptions. So even if you throw a `FileNotFoundException`, your users can react on `Tag\NotFoundTag` and still catch anything that can be thrown at them regarding something was not found while processing the request. Now **that is interoperability**. [Learn more](tags.md) - -# Defaults and From helpers - -There is no easy way to extract a message from an exception's class nor its error code. When you want to use an exception and just pass on a previous exception into it, the 3rd parameter is the only way to do this. But what if you didn't know what was the original message? - -Using the `from` and `defaults` helpers, this problem can be easily solved. All exceptions from this package implement those helpers. - -[Learn more](helpers.md) diff --git a/docs/helpers.md b/docs/helpers.md deleted file mode 100644 index 7d33a5e..0000000 --- a/docs/helpers.md +++ /dev/null @@ -1,92 +0,0 @@ -# Helpers - -There are a few helpers available. They range from storage of contextual data to rethrowing exceptions, read on! - -## DefaultsInterface - -All exceptions from this package implement this helper. This first helper defines that all exceptions must define a `getDefaultMessage` and a `getDefaultCode`. This allows you to get the default message and default code using a static call on the exception class like so: - -```php -$exceptionMessage = \Exceptions\Some\Thing::getDefaultMessage(); -$exceptionCode = \Exceptions\Some\Thing::getDefaultCode(); -``` - -> The value of these functions is doubtful until you start using the next helper - -## DefaultConstructorTrait - -All exceptions from this package implement this helper. This second helper helps you override the constructor of your exception by defining default values for your constructor and if nothing is passed, then, it will use the `getDefaultMessage` and `getDefaultCode` from the previous helper for you. - -> The value of this helper is interesting but really shines with the last helper! - -## FromException trait - -All exceptions from this package implement this helper. This third helper defines a static method on the exception you want to throw a new copy of itself using the previous helpers `getDefaultMessage` and `getDefaultCode`. The advantage is this method allows you to pass another exception to be set into the `$previousException` parameter that is always 3rd. - -This allows you to easily throw chains of exceptions without knowing the default message and code of that exception you want to throw. Example: - -```php -} catch (SomeException $ex){ - throw \Exceptions\Some\Thing::from($ex); -} -``` - -The other approach to this, without using `from()` looks like this: - -```php -} catch (SomeException $ex){ - throw new \Exceptions\Some\Thing( - \Exceptions\Some\Thing::getDefaultMessage(), - \Exceptions\Some\Thing::getDefaultCode(), - $ex - ); -} -``` - -Or even worst, if you don't use the defaults helpers, you have to hard code the message and code yourself: - -```php -} catch (SomeException $ex){ - throw new \Exceptions\Some\Thing( - 'An error occured because of something', - 19985, - $ex - ); -} -``` - -This clearly shows the advantage of the `FromException` trait. - -## WithContext trait - -All exceptions from this package implement this helper. This helper defines a static method on the exception you want to throw to attach contextual data to it before throwing it. You can use the `withContext` method to generate an exception with some data and the use `getContext` to retrieve it. - -For example: - -```php -throw new \Exceptions\Some\Thing::withContext(['some' => 'data']) -``` - -To retrieve the data: - -```php -} catch(\Exceptions\Some\Thing $ex) { - var_dump($ex->getContext()); -} -``` - -## HttpExceptionFactory - -This factory can help you to get an HttpException corresponding to a given Http Code - -```php -// Will return an exception of class \Exceptions\Http\Client\ImATeapotException -\Exceptions\Helper\HttpExceptionFactory::build(418); -``` - -Context is also supported - -```php -// Will return an exception of class \Exceptions\Http\Client\ImATeapotException -\Exceptions\Helper\HttpExceptionFactory::buildWithContext(418, ['some' => 'data']); -``` diff --git a/docs/index.md b/docs/index.md index 073f6ce..c004ec4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,4 +1,4 @@ -[![Latest Stable Version](https://poser.pugx.org/crazycodr/standard-exceptions/version.png)](https://packagist.org/packages/crazycodr/standard-exceptions) [![Monthly Downloads](https://poser.pugx.org/crazycodr/standard-exceptions/d/monthly)](https://packagist.org/packages/crazycodr/standard-exceptions) [![Build Status](https://travis-ci.org/crazycodr/standard-exceptions.png?branch=master)](https://travis-ci.org/crazycodr/standard-exceptions) +[![Latest Stable Version](https://poser.pugx.org/crazycodr/standard-exceptions/version.png)](https://packagist.org/packages/crazycodr/standard-exceptions) [![Monthly Downloads](https://poser.pugx.org/crazycodr/standard-exceptions/d/monthly)](https://packagist.org/packages/crazycodr/standard-exceptions) # Standard Exceptions Package @@ -10,6 +10,7 @@ Many exceptions that are missing from the SPL are constantly being reproduced in * [Getting started](getting-started.md) * [Upgrading from version 1 to version 2](upgrade-1-2.md) + * [Upgrading from version 2 to version 3](upgrade-2-3.md) * Exceptions and namespaces * [Collection exceptions](exceptions/collection-exceptions.md) * [Data exceptions](exceptions/data-exceptions.md) @@ -21,5 +22,5 @@ Many exceptions that are missing from the SPL are constantly being reproduced in * [Network exceptions](exceptions/io-network-exceptions.md) * [Operation exceptions](exceptions/operation-exceptions.md) * [Tags](tags.md) -* [Helpers](helpers.md) +* [Patterns](patterns.md) * [Contributing](contribute.md) diff --git a/docs/patterns.md b/docs/patterns.md new file mode 100644 index 0000000..74ed880 --- /dev/null +++ b/docs/patterns.md @@ -0,0 +1,79 @@ +# Usage patterns + +## Throwing non-generic exceptions + +Throwing an exception seems trivial but a lot of people often do following error: Throw a more generic exception and set a custom error message on it. + +While this might seem like a good approach, it isn't. If you do so, another piece of code cannot whole fully understand the reason why you are throwing an exception. + +When throwing exceptions, you should throw domain exceptions. This means that if you have a file not found in regard to a certain process such as a configuration file, you could throw a simple `FileNotFoundException` but what you should to is throw a `ConfigurationFileNotFoundException` as such: + +```php +class ConfigurationFileNotFoundException + extends FileNotFoundException { +} +``` + +When you do this, you create a sub classification of `FileNotFoundException` that anyone can catch, but you create a more defined context for your module that people can use to understand what went wrong at the right moment. + +## Access to defaults + +To make things normalized, all exceptions implement the [DefaultsInterface](../Helpers/DefaultsInterface.php). This interface allows easy static retrieval of core data of each exception: + +- `getDefaultMessage()`: Returns the default message of the exception. +- `getDefaultCode()`: Returns the default error code, in case of http errors, this is usually the http status code. + +You do not need to use this when throwing exceptions as the constructor of every exception in this package will automatically resolve the message and code using these functions for you. + +If you create new exceptions and need to override an exception's message, you can define a different message in the constant `MESSAGE` of the exception, or you can override `getDefaultMessage`: + +```php +class ConfigurationFileNotFoundException extends FileNotFoundException +{ + public const MESSAGE = 'The configuration file was not found'; + public const CODE = 108851; +} +``` + +## Rethrowing and nesting exceptions + +While it seems logical to rethrow exceptions and catch them higher up in your code, doing so is against proper coding practices because all consumers of a module should not be aware of the modules under it. This means you should always rethrow exceptions by nesting them under another exception and limit the scope they express to something that you can express. + +To nest an exception, use named parameters like depicted below: + +```php +try { + // do something +} catch (NestedExceptionType $ex) { + throw new DomainException(previous: $ex); +} +``` + +For example, a `YamlLoader` fails to parse a file, your `ConfigurationLoader` should not throw the format or parsing exception that the yaml loader throws, it should instead throw your own exception such as `ConfigurationParsingException`. + +```php +try { + Try to parse a yaml configuration file +} catch (YamlParsingException $ex) { + throw new ConfigurationParsingException(previous: $ex); +} +``` + +## Adding details to your exception + +While it might seem common or useful, most exceptions do not carry extra information around because they usually are not useful. Most exceptions being abortions of a process, knowing why something fails should be expressed by the intent that the exception represents and the moment when an exception occurs, not by reading underlying data. + +Nonetheless, if you want to add custom data to your exceptions, do it properly by respecting the original exception pattern. Your exception does not need to allow overriding messages and codes, but you must support previous exceptions so that nesting can be done properly. + +That being said, your constructor should look something like this: + +```php +public function __construct( + private readonly string $customData, + null|Throwable $previous = null +) { + parent::__construct(previous: $previous); +} +``` + +By doing so, you allow your exception to support `customData`, readonly at the same time, and you still support `previous` exceptions. diff --git a/docs/tags.md b/docs/tags.md index ec278ca..3538ac4 100644 --- a/docs/tags.md +++ b/docs/tags.md @@ -21,23 +21,9 @@ The `Tag\` namespace contains different interfaces that help you convey the same All tags are found under `\Exceptions\Tag`. -### Aborted tag +### Already exists tag -The `AbortedTag` interface is assigned to any exception that declares that the operation you tried to execute was aborted due to an underlying failure. - -> **DEPRECATION WARNING**: We've been going a little too crazy with the usage of `AbortedTa`g. Because of this, `AbortedTag` is now deprecated with no exact replacement scenario for now. Avoid adding `AbortedTag` to new exceptions you create as it is a little too widespread right now and doesn't convey a proper means vs context. - -> **IMPORTANT NOTES**: This was previously named `OperationAbortedException` and was recently renamed. You can still use `OperationAbortedException` to catch exceptions that extend the `AbortedTag` but you cannot use the `AbortedTag` to catch old exceptions you created in your project that implement `OperationAbortedExceptio`n. -> -> `OperationAbortedException` is deprecated as of the latest version and will be removed in version 3.0 - -### Exists tag - -The `ExistsTag` interface is assigned to any exception that declares that the operation you tried to execute failed because the entity you tried to add to some kind of collection or lot of items already existed. - -> **IMPORTANT NOTES**: This was previously named `AlreadyExistsException` and was recently renamed. You can still use `AlreadyExistsException` to catch exceptions that extend the `ExistsTag` but you cannot use the `ExistsTag` to catch old exceptions you created in your project that implement `OperationAbortedExceptio`n. -> -> `AlreadyExistsException` is deprecated as of the latest version and will be removed in version 3.0 +The `AlreadyExistsTag` interface is assigned to any exception that declares that the operation you tried to execute failed because the entity you tried to add to some kind of collection or a lot of items already existed. ### Forbidden tag @@ -51,22 +37,14 @@ The `InvalidDataTag` interface is assigned to any exception that declares that t You should consider mapping this tag to anything that is configuration wise or data type validation wise operations that would fail. -> **IMPORTANT NOTES**: This was previously named `InvalidDataException` and was recently renamed. You can still use `InvalidDataException` to catch exceptions that extend the `InvalidDataTag` but you cannot use the `InvalidDataTag` to catch old exceptions you created in your project that implement `OperationAbortedExceptio`n. -> -> `InvalidDataException` is deprecated as of the latest version and will be removed in version 3.0 - ### Not found tag The `NotFoundTag` interface is assigned to any exception that declares that the operation you tried to execute was not allowed because the entity you wanted to apply this operation on was not found. You should consider mapping this tag to anything that is about searching for data and not finding it. It could be database wise, api wise, filesystem wise. Just think: "I could not find that resource". -> **IMPORTANT NOTES**: This was previously named `NotFoundException` and was recently renamed. You can still use `NotFoundException` to catch exceptions that extend the `NotFoundTag` but you cannot use the `NotFoundTag` to catch old exceptions you created in your project that implement `OperationAbortedExceptio`n. -> -> `NotFoundException` is deprecated as of the latest version and will be removed in version 3.0 - ### Unauthorized tag The `UnauthorizedTag` interface is assigned to any exception that declares that the operation you tried to execute was not allowed because we could not identify you. Thus, you should attempt this operation again only if you provide proper credentials or means of identity. -Don't confuse `UnauthorizedTag` and `ForbiddenTag`, one is about permission being denied, the other is about missing authentication which could resolve into a `ForbiddenTag` if you didn't want to take care of authentication issues. \ No newline at end of file +Don't confuse `UnauthorizedTag` and `ForbiddenTag`, one is about permission being denied, the other is about missing authentication which could resolve into a `ForbiddenTag` if you didn't want to take care of authentication issues. diff --git a/docs/upgrade-1-2.md b/docs/upgrade-1-2.md index 62fc611..fd27988 100644 --- a/docs/upgrade-1-2.md +++ b/docs/upgrade-1-2.md @@ -5,17 +5,17 @@ Below is a list of changes between version 1 and version 2. You can refer to thi Considering this library is not a features library, there is no difference in the usage pattern, there are just different exceptions to thrown or namespaces to use. ## Namespace rename or change -| Old | New | -| --- | --- | -| StandardExceptions | Exceptions | -| ArrayExceptions | Collection | -| HTTPExceptions | Http | -| IOExceptions | IO | -| LogicExceptions | Operation | -| OperationExceptions | Operation | -| ValidationExceptions | Data | +| Old | New | +|----------------------|------------| +| StandardExceptions | Exceptions | +| ArrayExceptions | Collection | +| HTTPExceptions | Http | +| IOExceptions | IO | +| LogicExceptions | Operation | +| OperationExceptions | Operation | +| ValidationExceptions | Data | -## Namespace that have disapeared +## Namespace that have disappeared - LogicExceptions ## New namespaces @@ -26,33 +26,33 @@ Considering this library is not a features library, there is no difference in th ## Exceptions that have moved or renamed ------------------------------------- -| Old | New | -| --- | --- | -| ArrayExceptions\ArrayIsEmptyException | Collection\EmptyException | -| ArrayExceptions\ArrayIsFullException | Collection\FullException | -| HTTPExceptions\BadRequestException | Http\Client\BadRequestException | -| HTTPExceptions\ForbiddenException | Http\Client\ForbiddenException | -| HTTPExceptions\MethodNotAllowedException | Http\Client\MethodNotAllowedException | -| HTTPExceptions\NotAcceptableException | Http\Client\NotAcceptableException | -| HTTPExceptions\NotFoundException | Http\Client\NotFoundException | -| HTTPExceptions\UnauthorizedException | Http\Client\UnauthorizedException | -| HTTPExceptions\UnprocessableEntityException | Http\Client\UnprocessableEntityException | -| IOExceptions\DirectoryNotFoundException | IO\Filesystem\DirectoryNotFoundException | -| IOExceptions\DirectoryNotReadableException | IO\Filesystem\DirectoryNotReadableException | -| IOExceptions\DirectoryNotWritableException | IO\Filesystem\DirectoryNotWritableException | -| IOExceptions\FileNotFoundException | IO\Filesystem\FileNotFoundException | -| IOExceptions\FileNotReadableException | IO\Filesystem\FileNotReadableException | -| IOExceptions\FileNotWritableException | IO\Filesystem\FileNotWritableException | -| IOExceptions\NotADirectoryException | IO\Filesystem\NotADirectoryException | -| IOExceptions\NotAFileException | IO\Filesystem\NotAFileException | -| IOExceptions\ConnectionLostException | IO\Network\ConnectionLostException | -| IOExceptions\ConnectionRefusedException | IO\Network\ConnectionRefusedException | -| IOExceptions\UnexpectedResponseException | IO\Network\UnexpectedResponseException | -| IOExceptions\UnknownHostException | IO\Network\UnknownHostException | -| OperationExceptions\NotImplementedYetException | Operation\NotImplementedException | -| OperationExceptions\UnexpectedReturnValueException | Operation\UnexpectedException | +| Old | New | +|----------------------------------------------------|---------------------------------------------| +| ArrayExceptions\ArrayIsEmptyException | Collection\EmptyException | +| ArrayExceptions\ArrayIsFullException | Collection\FullException | +| HTTPExceptions\BadRequestException | Http\Client\BadRequestException | +| HTTPExceptions\ForbiddenException | Http\Client\ForbiddenException | +| HTTPExceptions\MethodNotAllowedException | Http\Client\MethodNotAllowedException | +| HTTPExceptions\NotAcceptableException | Http\Client\NotAcceptableException | +| HTTPExceptions\NotFoundException | Http\Client\NotFoundException | +| HTTPExceptions\UnauthorizedException | Http\Client\UnauthorizedException | +| HTTPExceptions\UnprocessableEntityException | Http\Client\UnprocessableEntityException | +| IOExceptions\DirectoryNotFoundException | IO\Filesystem\DirectoryNotFoundException | +| IOExceptions\DirectoryNotReadableException | IO\Filesystem\DirectoryNotReadableException | +| IOExceptions\DirectoryNotWritableException | IO\Filesystem\DirectoryNotWritableException | +| IOExceptions\FileNotFoundException | IO\Filesystem\FileNotFoundException | +| IOExceptions\FileNotReadableException | IO\Filesystem\FileNotReadableException | +| IOExceptions\FileNotWritableException | IO\Filesystem\FileNotWritableException | +| IOExceptions\NotADirectoryException | IO\Filesystem\NotADirectoryException | +| IOExceptions\NotAFileException | IO\Filesystem\NotAFileException | +| IOExceptions\ConnectionLostException | IO\Network\ConnectionLostException | +| IOExceptions\ConnectionRefusedException | IO\Network\ConnectionRefusedException | +| IOExceptions\UnexpectedResponseException | IO\Network\UnexpectedResponseException | +| IOExceptions\UnknownHostException | IO\Network\UnknownHostException | +| OperationExceptions\NotImplementedYetException | Operation\NotImplementedException | +| OperationExceptions\UnexpectedReturnValueException | Operation\UnexpectedException | -## Exceptions that have disapeared +## Exceptions that have disappeared - ArrayExceptions\ArrayUnderflowException (Was deprecated, use Collection\EmptyException instead) - ArrayExceptions\IndexNotFoundException (Was deprecated, use Collection\KeyNotFoundException instead) - ArrayExceptions\InvalidKeyException (Changed for Data\FormatException) @@ -80,4 +80,4 @@ Considering this library is not a features library, there is no difference in th - Http\Client\UnsupportedMediaTypeException - Http\Server\InternalServerErrorException - Http\Server\NotImplementedException -- Http\Server\ServiceUnavailableException \ No newline at end of file +- Http\Server\ServiceUnavailableException diff --git a/docs/upgrade-2-3.md b/docs/upgrade-2-3.md new file mode 100644 index 0000000..eec4883 --- /dev/null +++ b/docs/upgrade-2-3.md @@ -0,0 +1,116 @@ +# Changes between version 2 and version 3 + +Below is a list of changes between version 2 and version 3. You can refer to this list to know what you should be replacing with what. This is a comprehensive list of all the changes. + +There are several pattern differences between version 2 and 3 which will be discussed below. + +# Testing strategy + +Testing has been completely removed because there isn't really anything to test. + +Previous tests were used to ensure that the dependencies between exceptions didn't change but that should be handled through reviews. + +Because there are no features to actually test, tests have been removed. This doesn't mean the library can't be proved as stable, it is stable but there is nothing to test. + +The only build status we can now infer will be the linting status. + +# Pattern changes and possible breaking changes + +## Type constraints + +By moving to PHP 8, every method and constructor has been upgraded to have argument and return types. + +This might have issues if you improperly used `$message` or `$code` in your exceptions because these are now `string` and `int` based. + +## Scope definitions + +Every constant and method have been officially declared `public` like they should have been. Unless you willfully went against this by making certain methods or constant `protected` or `private`, this should not have any consequence. + +## Helpers completely removed + +There were different helpers that existed previously to facilitate certain patterns such as nesting and rethrowing, allowing contextual data and such. + +> Except for the defaults helper which is a base interface to enable easier access to messages and codes, all helpers have been removed. + +### From helper + +This helper was used to simplify nesting and rethrowing but isn't necessary in PHP 8. We can easily rethrow an exception into a new one by using named parameters. Therefore, you should convert all existing use cases from: + +```php +try { + // do something +} catch (NestedExceptionType $ex) { + throw DomainException::from($ex); +} +``` + +To the following format: + +```php +try { + // do something +} catch (NestedExceptionType $ex) { + throw new DomainException(previous: $ex); +} +``` + +## Context helper + +This helper was used to add contextual data easily to any exception. This goes against proper type safety practices, so it was removed. + +The data stored in an exception is often misused or unnecessary because the exception itself and the location you catch the error should be enough to understand the context. The fact it wasn't typed is worst because it means you need to type cast it, but it doesn't prevent errors from happening if the underlying module throwing forgot to attach data or changed the structure. + +Instead of doing this: + +```php +throw ContextualException::withContext($data, ...); +``` + +Change to the following format: + +```php +class ContextualException extends ... { + public function __construct( + private readonly string $customData, + null|Throwable $previous = null + ) { + parent::__construct(previous: $previous); + } +} + +throw new ContextualException($data); +// or +throw new ContextualException(customData: $data, previous: $ex); +``` + +## Http exception factory + +This factory was introduced late into version 2 to help people generate the appropriate HTTP exception based on a classic HTTP status code that you would return. This is now proscribed as it goes against the concepts of domain driven exceptions. + +When an exception is thrown, the module throwing it expresses a reason for improperly working. It should not be throwing an HTTP exception unless it is running in the context of an HTTP transaction. This means that only a controller should actually know about HTTP status codes. Underlying code in your services or data layer should throw non HTTP contextual exceptions that get transformed into an HTTP exception or message in the end. + +There is no replacement for this, you will have to look at best practices for your framework on how to properly set up an exception management module that transforms domain exceptions into errors. What you should consider is using [tags](tags.md). + +# Exceptions that have been replaced + +The following exceptions or tags have been replaced with a new item. All of these were originally deprecated and have been officially removed from the codebase. + +| Old | New | +|-------------------------------------|---------------------------------| +| Exceptions\Tag\ExistsTag | Exceptions\Tag\AlreadyExistsTag | +| Exceptions\Tag\InvalidDataException | Exceptions\Tag\InvalidDataTag | +| Exceptions\Tag\NotFoundException | Exceptions\Tag\NotFoundTag | + +# Exceptions, tags and helpers that have disappeared without a replacement + +Certain classes simply disappeared, see the [patterns](patterns.md) this package suggests to overcome the loss of these files. + +- Exceptions\Helpers\DefaultConstructorTrait +- Exceptions\Helpers\FromException +- Exceptions\Helpers\HttpExceptionFactory +- Exceptions\Helpers\WithContext +- Exceptions\Http\Client\ImATeapotException +- Exceptions\Http\Client\RequestEntityTooLargeException +- Exceptions\Http\Client\RequestedRangeNotSatisfiableException +- Exceptions\Tag\AbortedTag +- Exceptions\Tag\OperationAbortedException diff --git a/phpunit.php b/phpunit.php deleted file mode 100644 index 306a3df..0000000 --- a/phpunit.php +++ /dev/null @@ -1,4 +0,0 @@ - - - - - - Tests - - - - - - ./Exceptions - ./Helpers/HttpExceptionFactory.php - - - - - - - - - -