2023-12-28 12:33:06 +04:00
|
|
|
<?php
|
|
|
|
namespace nulib;
|
|
|
|
|
2023-12-31 19:34:12 +04:00
|
|
|
use RuntimeException;
|
2023-12-28 12:33:06 +04:00
|
|
|
use Throwable;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class UserException: une exception qui peut en plus contenir un message
|
|
|
|
* utilisateur
|
|
|
|
*/
|
2023-12-31 19:34:12 +04:00
|
|
|
class UserException extends RuntimeException {
|
2023-12-28 12:33:06 +04:00
|
|
|
/** @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;
|
|
|
|
}
|
|
|
|
}
|