modifs.mineures sans commentaires
This commit is contained in:
parent
8cf225ea1e
commit
43b7b046fa
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
namespace nulib;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class ExceptionShadow: une classe qui capture les informations d'une
|
||||
* exception afin de pouvoir les sérialiser
|
||||
*/
|
||||
class ExceptionShadow {
|
||||
protected static function extract_trace(array $trace): array {
|
||||
$frames = [];
|
||||
foreach ($trace as $frame) {
|
||||
$file = cl::get($frame, "file");
|
||||
$line = cl::get($frame, "line");
|
||||
$class = cl::get($frame, "class");
|
||||
$function = cl::get($frame, "function");
|
||||
$type = cl::get($frame, "type");
|
||||
$frames[] = [
|
||||
"file" => $file,
|
||||
"line" => $line,
|
||||
"class" => $class,
|
||||
"object" => null,
|
||||
"type" => $type,
|
||||
"function" => $function,
|
||||
"args" => [],
|
||||
];
|
||||
}
|
||||
return $frames;
|
||||
}
|
||||
|
||||
function __construct(Throwable $exception) {
|
||||
$this->class = get_class($exception);
|
||||
$this->message = $exception->getMessage();
|
||||
$this->code = $exception->getCode();
|
||||
$this->file = $exception->getFile();
|
||||
$this->line = $exception->getLine();
|
||||
$this->trace = self::extract_trace($exception->getTrace());
|
||||
$previous = $exception->getPrevious();
|
||||
if ($previous !== null) $this->previous = new static($previous);
|
||||
}
|
||||
|
||||
/** @var string */
|
||||
protected $class;
|
||||
|
||||
function getClass(): string {
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
/** @var string */
|
||||
protected $message;
|
||||
|
||||
function getMessage(): string {
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
/** @var mixed */
|
||||
protected $code;
|
||||
|
||||
function getCode() {
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
/** @var string */
|
||||
protected $file;
|
||||
|
||||
function getFile(): string {
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
/** @var int */
|
||||
protected $line;
|
||||
|
||||
function getLine(): int {
|
||||
return $this->line;
|
||||
}
|
||||
|
||||
/** @var array */
|
||||
protected $trace;
|
||||
|
||||
function getTrace(): array {
|
||||
return $this->trace;
|
||||
}
|
||||
|
||||
function getTraceAsString(): string {
|
||||
$lines = [];
|
||||
foreach ($this->trace as $index => $frame) {
|
||||
$lines[] = "#$index $frame[file]($frame[line]): $frame[class]$frame[type]$frame[function]()";
|
||||
}
|
||||
$index++;
|
||||
$lines[] = "#$index {main}";
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/** @var ExceptionShadow */
|
||||
protected $previous;
|
||||
|
||||
function getPrevious(): ?ExceptionShadow {
|
||||
return $this->previous;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
namespace nulib;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class ExitException: une exception qui indique que l'application souhaite
|
||||
* quitter normalement, avec éventuellement un code d'erreur.
|
||||
*/
|
||||
class ExitException extends UserException {
|
||||
function __construct(int $exitcode=0, $user_message=null, Throwable $previous=null) {
|
||||
parent::__construct($user_message, null, $exitcode, $previous);
|
||||
}
|
||||
|
||||
function isError(): bool {
|
||||
return $this->getCode() !== 0;
|
||||
}
|
||||
|
||||
function haveMessage(): bool {
|
||||
return $this->getUserMessage() !== null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
namespace nulib;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class StopException: une exception qui par convention est envoyée à un
|
||||
* générateur pour indiquer qu'il doit s'arrêter "proprement". cela peut être
|
||||
* utilisé pour implémenter des itérateur "closeable"
|
||||
*/
|
||||
class StopException extends Exception {
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
namespace nulib;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class UserException: une exception qui peut en plus contenir un message
|
||||
* utilisateur
|
||||
*/
|
||||
class UserException extends Exception {
|
||||
/** @param Throwable|ExceptionShadow $e */
|
||||
static function get_user_message($e): ?string {
|
||||
if ($e instanceof self) return $e->getUserMessage();
|
||||
else return null;
|
||||
}
|
||||
|
||||
/** @param Throwable|ExceptionShadow $e */
|
||||
static final function get_user_summary($e): string {
|
||||
$parts = [];
|
||||
$first = true;
|
||||
while ($e !== null) {
|
||||
$message = self::get_user_message($e);
|
||||
if (!$message) $message = "(no message)";
|
||||
if ($first) $first = false;
|
||||
else $parts[] = "caused by ";
|
||||
$parts[] = get_class($e) . ": " . $message;
|
||||
$e = $e->getPrevious();
|
||||
}
|
||||
return implode(", ", $parts);
|
||||
}
|
||||
|
||||
/** @param Throwable|ExceptionShadow $e */
|
||||
static function get_message($e): ?string {
|
||||
$message = $e->getMessage();
|
||||
if (!$message && $e instanceof self) $message = $e->getUserMessage();
|
||||
return $message;
|
||||
}
|
||||
|
||||
/** @param Throwable|ExceptionShadow $e */
|
||||
static final function get_summary($e): string {
|
||||
$parts = [];
|
||||
$first = true;
|
||||
while ($e !== null) {
|
||||
$message = self::get_message($e);
|
||||
if (!$message) $message = "(no message)";
|
||||
if ($first) $first = false;
|
||||
else $parts[] = "caused by ";
|
||||
if ($e instanceof ExceptionShadow) $class = $e->getClass();
|
||||
else $class = get_class($e);
|
||||
$parts[] = "$class: $message";
|
||||
$e = $e->getPrevious();
|
||||
}
|
||||
return implode(", ", $parts);
|
||||
}
|
||||
|
||||
/** @param Throwable|ExceptionShadow $e */
|
||||
static final function get_traceback($e): string {
|
||||
$tbs = [];
|
||||
$previous = false;
|
||||
while ($e !== null) {
|
||||
if (!$previous) {
|
||||
$efile = $e->getFile();
|
||||
$eline = $e->getLine();
|
||||
$tbs[] = "at $efile($eline)";
|
||||
} else {
|
||||
$tbs[] = "~~ caused by: " . self::get_summary($e);
|
||||
}
|
||||
$tbs[] = $e->getTraceAsString();
|
||||
$e = $e->getPrevious();
|
||||
$previous = true;
|
||||
#XXX il faudrait ne pas réinclure les lignes communes aux exceptions qui
|
||||
# ont déjà été affichées
|
||||
}
|
||||
return implode("\n", $tbs);
|
||||
}
|
||||
|
||||
function __construct($user_message, $tech_message=null, $code=0, ?Throwable $previous=null) {
|
||||
$this->userMessage = $user_message;
|
||||
if ($tech_message === null) $tech_message = $user_message;
|
||||
parent::__construct($tech_message, $code, $previous);
|
||||
}
|
||||
|
||||
protected $userMessage;
|
||||
|
||||
function getUserMessage(): ?string {
|
||||
return $this->userMessage;
|
||||
}
|
||||
}
|
|
@ -1,12 +1,10 @@
|
|||
<?php
|
||||
namespace nulib;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class ValueException: indiquer qu'une valeur est invalide
|
||||
*/
|
||||
class ValueException extends Exception {
|
||||
class ValueException extends UserException {
|
||||
private static function value($value): string {
|
||||
if (is_object($value)) {
|
||||
return "<".get_class($value).">";
|
||||
|
@ -40,11 +38,23 @@ class ValueException extends Exception {
|
|||
return new static(self::message(null, $message, $kind, $prefix, " is null"));
|
||||
}
|
||||
|
||||
static final function invalid($value=null, ?string $kind=null, ?string $prefix=null, ?string $message=null): self {
|
||||
static final function invalid_kind($value=null, ?string $kind=null, ?string $prefix=null, ?string $message=null): self {
|
||||
return new static(self::message($value, $message, $kind, $prefix, " is invalid"));
|
||||
}
|
||||
|
||||
static final function unexpected_class($class, string $expected_class) {
|
||||
static final function invalid_key($value, ?string $prefix=null, ?string $message=null): self {
|
||||
return self::invalid_kind($value, "key", $prefix, $message);
|
||||
}
|
||||
|
||||
static final function invalid_value($value, ?string $prefix=null, ?string $message=null): self {
|
||||
return self::invalid_kind($value, "value", $prefix, $message);
|
||||
}
|
||||
|
||||
static final function invalid_type($value, string $expected_type): self {
|
||||
return new static(self::message($value, null, "type", null, " is invalid, expected $expected_type"));
|
||||
}
|
||||
|
||||
static final function invalid_class($class, string $expected_class): self {
|
||||
if (is_object($class)) $class = get_class($class);
|
||||
return new static(self::message($class, null, "class", null, " is invalid, expected $expected_class"));
|
||||
}
|
||||
|
|
|
@ -181,7 +181,7 @@ class cv {
|
|||
$index = is_int($value)? $value : null;
|
||||
$key = is_string($value)? $value : null;
|
||||
if ($index === null && $key === null && $throw_exception) {
|
||||
throw ValueException::invalid($value, "key", $prefix);
|
||||
throw ValueException::invalid_kind($value, "key", $prefix);
|
||||
} else {
|
||||
return [$index, $key];
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ class cv {
|
|||
$string = is_string($value)? $value : null;
|
||||
$array = is_array($value)? $value : null;
|
||||
if ($bool === null && $string === null && $array === null && $throw_exception) {
|
||||
throw ValueException::invalid($value, "value", $prefix);
|
||||
throw ValueException::invalid_kind($value, "value", $prefix);
|
||||
} else {
|
||||
return [$bool, $string, $array];
|
||||
}
|
||||
|
|
|
@ -348,7 +348,7 @@ class str {
|
|||
} elseif (preg_match(self::CAMEL_PATTERN2, $camel, $vs, PREG_OFFSET_CAPTURE)) {
|
||||
# préfixe en minuscule
|
||||
} else {
|
||||
throw ValueException::invalid($camel, "camel string");
|
||||
throw ValueException::invalid_kind($camel, "camel string");
|
||||
}
|
||||
$parts[] = strtolower($vs[1][0]);
|
||||
$index = intval($vs[1][1]) + strlen($vs[1][0]);
|
||||
|
|
|
@ -4,11 +4,11 @@ namespace nulib;
|
|||
use nulib\tests\TestCase;
|
||||
|
||||
class ValueExceptionTest extends TestCase {
|
||||
function testUnexpectedClass() {
|
||||
$e = ValueException::unexpected_class(null, self::class);
|
||||
function testInvalidClass() {
|
||||
$e = ValueException::invalid_class(null, self::class);
|
||||
self::assertSame("class is invalid, expected ".self::class, $e->getMessage());
|
||||
|
||||
$e = ValueException::unexpected_class(ValueException::class, self::class);
|
||||
$e = ValueException::invalid_class(ValueException::class, self::class);
|
||||
self::assertSame(ValueException::class.": class is invalid, expected ".self::class, $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue