Skip to content

Commit

Permalink
Update codebase and documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Nov 28, 2023
1 parent 24afa8d commit 3ff2547
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 25 deletions.
27 changes: 13 additions & 14 deletions src/Error/Cloak.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@

use Closure;
use ErrorException;

use ValueError;

use function error_reporting;
use function restore_error_handler;
use function set_error_handler;

Expand All @@ -21,8 +19,8 @@ class Cloak

protected static bool $useException = false;

protected CloakedErrors $errors;
protected readonly ErrorLevel $errorLevel;
protected CloakedErrors $errors;

/**
* @throws ValueError
Expand Down Expand Up @@ -96,24 +94,25 @@ public static function all(Closure $closure, int $onError = self::FOLLOW_ENV): s
return new self($closure, $onError, 'E_ALL');
}

protected function errorHandler(int $errno, string $errstr, string $errfile, int $errline): bool
{
if (ErrorLevel::fromEnvironment()->doesNotContain($errno)) {
return false;
}

$this->errors->unshift(new ErrorException($errstr, 0, $errno, $errfile, $errline));

return true;
}

/**
* @throws CloakedErrors
*/
public function __invoke(mixed ...$arguments): mixed
{
$this->errors = new CloakedErrors();
$errorHandler = function (int $errno, string $errstr, string $errfile, int $errline): bool {
if (0 === (error_reporting() & $errno)) {
return false;
}

$this->errors->unshift(new ErrorException($errstr, 0, $errno, $errfile, $errline));

return true;
};

try {
set_error_handler($errorHandler, $this->errorLevel->value());
set_error_handler($this->errorHandler(...), $this->errorLevel->value());
$result = ($this->closure)(...$arguments);
} finally {
restore_error_handler();
Expand Down
13 changes: 7 additions & 6 deletions src/Error/CloakedErrors.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
*/
final class CloakedErrors extends RuntimeException implements Countable, IteratorAggregate
{
/**
* @param array<ErrorException> $errors
*/
public function __construct(
private array $errors = []
) {
/** @var array<ErrorException> */
private array $errors;

public function __construct(ErrorException ...$errors)
{
parent::__construct();

$this->errors = $errors;
}

public function count(): int
Expand Down
19 changes: 18 additions & 1 deletion src/Error/ErrorLevel.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

use ValueError;

use function array_key_exists;
use function array_filter;
use function array_key_exists;
use function array_map;
use function array_reduce;
use function array_search;
Expand Down Expand Up @@ -60,11 +60,17 @@ protected function __construct(protected readonly int $value)
}
}

/**
* Returns a new instance by using the error reporting level value.
*/
public static function fromValue(int $value): self
{
return new self($value);
}

/**
* Returns a new instance by using the error reporting level constant name.
*/
public static function fromName(string $name): self
{
/** @var int|false $errorLevel */
Expand All @@ -81,6 +87,9 @@ public static function fromEnvironment(): self
return new self(error_reporting());
}

/**
* Returns a new instance by excluded error levels from E_ALL.
*/
public static function fromExclusion(self|string|int ...$levels): self
{
return new self(array_reduce($levels, function (int $carry, self|string|int $level) {
Expand All @@ -98,6 +107,9 @@ public static function fromExclusion(self|string|int ...$levels): self
}, E_ALL));
}

/**
* Returns a new instance by adding error levels from the initial no error reporting level.
*/
public static function fromInclusion(self|string|int ...$levels): self
{
return new self(array_reduce($levels, function (int $carry, self|string|int $level) {
Expand All @@ -120,6 +132,11 @@ public function value(): int
return $this->value;
}

public function doesNotContain(self|string|int ...$levels): bool
{
return !$this->contains(...$levels);
}

public function contains(self|string|int ...$levels): bool
{
if ([] === $levels) {
Expand Down
30 changes: 26 additions & 4 deletions src/Error/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,12 @@ The class contains five (5) methods to ease working with error reporting level:

`ErrorLevel::fromValue` allow instantiating the class with any value you want. Alternatively, you can
instantiate the class to match your current environment settings using `ErrorLevel::fromEnvironment`.
`ErrorLevel::fromInclusion` instantiate the error level by adding all the submitted values via a
`ErrorLevel::fromInclusion` instantiates the error level by adding all the submitted values via a
bitwise `OR` operation starting at `0` meaning that no Error reporting level exists if none is added.
Conversely `ErrorLevel::fromExclusion` does the opposite, each value given will be remove from the
Conversely `ErrorLevel::fromExclusion` does the opposite, each value given will be removed from the
maximum value `E_ALL`.

Last but not least you can tell which error reporting is being configured using the `contains` method.
You can tell which error reporting is being configured using the `contains` method.

```php
<?php
Expand All @@ -210,10 +210,32 @@ use Bakame\Aide\Error\ErrorLevel;
ErrorLevel::fromEnvironment()->contains(E_WARNING);
// returns true if the current value in error_reporting contains `E_WARNING`
// returns false otherwise.
```

The class also provides the `excluded` and `included` methods which returns the
error reporting level names.

```php
<?php

use Bakame\Aide\Error\ErrorLevel;

$errorLevel = ErrorLevel::fromExclusion(E_NOTICE, E_DEPRECATED)->value();
ErrorLevel::fromEnvironment()->contains(E_WARNING);
// returns true if the current value in error_reporting contains `E_WARNING`
// returns false otherwise.

$errorLevel = ErrorLevel::fromInclusion(E_NOTICE, "E_DEPRECATED");

$errorLevel->value();
// `value` returns the int value corresponding to the calculated error level.
// the errorLevel calculated will ignore notice, and deprecated error.

$errorLevel->excluded();
// returns all the error reporting level name no present in the current error Level

$errorLevel->included();
// returns all the error reporting level name present in the current error Level
// ["E_NOTICE", "E_DEPRECATED"]
```

## Credits
Expand Down

0 comments on commit 3ff2547

Please sign in to comment.