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; } }