diff --git a/composer.json b/composer.json index 7dbf370..807d038 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,8 @@ } ], "require": { - "php" : "^8.1" + "php": "^8.1", + "psr/log": "^3.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "^v3.15.1", diff --git a/src/Error/Cloak.php b/src/Error/Cloak.php index fbd2d9e..da5ad68 100644 --- a/src/Error/Cloak.php +++ b/src/Error/Cloak.php @@ -7,6 +7,7 @@ use ArgumentCountError; use Closure; use ErrorException; +use Psr\Log\LoggerInterface; use ValueError; use function in_array; @@ -50,7 +51,8 @@ class Cloak public function __construct( protected readonly Closure $closure, protected readonly int $onError = self::OBEY, - ReportingLevel|string|int|null $reportingLevel = null + ReportingLevel|string|int|null $reportingLevel = null, + protected readonly ?LoggerInterface $logger = null ) { if (!in_array($this->onError, [self::SILENT, self::THROW, self::OBEY], true)) { throw new ValueError('The `onError` value is invalid; expect one of the `'.self::class.'` constants.'); @@ -110,7 +112,9 @@ protected function errorHandler(int $errno, string $errstr, string $errfile = nu } $this->errors->unshift(new ErrorException($errstr, 0, $errno, $errfile, $errline)); - + $this->logger?->error('An error occurred during execution of the closure attach to a `'.self::class.'` instance.', [ + 'exception' => $this->errors->last(), + ]); return $this->errorsAreThrown() ? throw $this->errors->last() : true; } @@ -124,19 +128,27 @@ public static function silentOnError(): void self::$useException = false; } - public static function env(Closure $closure, int $onError = self::OBEY): self - { - return new self($closure, $onError); + public static function env( + Closure $closure, + int $onError = self::OBEY, + ?LoggerInterface $logger = null + ): self { + return new self($closure, $onError, ReportingLevel::fromEnv(), $logger); } /** - * @param array{0:Closure, 1:self::OBEY|self::SILENT|self::THROW|null} $arguments + * @param array{0:Closure, 1:self::OBEY|self::SILENT|self::THROW|null, 2:LoggerInterface|null} $arguments */ public static function __callStatic(string $name, array $arguments): self { return match (true) { 1 > count($arguments) => throw new ArgumentCountError('The method expects at least 1 argument; '.count($arguments).' was given.'), - default => new self($arguments[0], $arguments[1] ?? self::OBEY, ReportingLevel::__callStatic($name)), + default => new self( + $arguments[0], + $arguments[1] ?? self::OBEY, + ReportingLevel::__callStatic($name), + $arguments[2] ?? null + ), }; } } diff --git a/src/Error/README.md b/src/Error/README.md index 33cc0d3..9757355 100644 --- a/src/Error/README.md +++ b/src/Error/README.md @@ -93,19 +93,6 @@ if (!$touch = Cloak::warning(touch(...), Cloak::SILENT)) { ## Available properties and methods -### Accessing the Error Reporting Level - -Once instantiated, you can always access the error reporting level via -the `errorLevel` method. For instance if you need to know if a -specific error is included you can do the following: - -```php -$touch = Cloak::all(touch(...)); -$touch->reportingLevel()->contains(E_WARNING); //tells if the E_WARNING is included or not -``` - -The method returns an `Bakame\Aide\Error\ReportingLevel` instance which is documented below. - ### Accessing the error To access the errors store in the instance you need to call the `Cloak::errors` method @@ -166,7 +153,7 @@ Cloak::userDeprecated(); They all share the same signature: ```php -static method(Closure $closure, int $onError = Cloak::OBEY); +static method(Closure $closure, int $onError = Cloak::OBEY, LoggerInterface $logger = null); ``` the `$onError` argument is used to tweak the instance behaviour on error: @@ -175,6 +162,8 @@ the `$onError` argument is used to tweak the instance behaviour on error: - `Cloak::SILENT` will override the general behaviour and silence the error if it exists - `Cloak::OBEY` will comply with the environment behaviour. +You can also give it a PSR compliant logger so that the error gets automatically logged. + If you really need other fined grained error level you can still use the constructor as shown below: @@ -185,10 +174,12 @@ use Bakame\Aide\Error\Cloak; $touch = new Cloak( touch(...), Cloak::THROW, - E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED + E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED, ); ``` +*The PSR compliant logger can also be given to the constructor* + ### ReportingLevel class The previous code example can be rewritten using the `ReportingLevel` class which ships with the package: @@ -201,7 +192,7 @@ use Bakame\Aide\Error\ReportingLevel; $touch = new Cloak( touch(...), Cloak::THROW, - ReportingLevel::fromExclusion(E_NOTICE, E_STRICT, E_DEPRECATED) + ReportingLevel::fromExclusion(E_NOTICE, E_STRICT, E_DEPRECATED), ); ``` @@ -252,6 +243,17 @@ $reportingLevel->included(); // ["E_NOTICE", "E_DEPRECATED"] ``` +### Accessing the Error Reporting Level + +Once instantiated, you can always access the error reporting level via +the `errorLevel` method on a `Cloak` instance. For example, if you need to know if a +specific error is included you can do the following: + +```php +$touch = Cloak::all(touch(...)); +$touch->reportingLevel()->contains(E_WARNING); //tells if the E_WARNING is included or not +``` + ## Credits - [Bishop Bettini and Haldayne PHP Componentry](https://github.com/haldayne/fox) diff --git a/src/Error/composer.json b/src/Error/composer.json index 7fdcafb..f8fd257 100644 --- a/src/Error/composer.json +++ b/src/Error/composer.json @@ -24,7 +24,8 @@ } ], "require": { - "php" : "^8.1" + "php" : "^8.1", + "psr/log": "^3.0" }, "autoload": { "psr-4": {