X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=mdref%2FExceptionHandler.php;h=eaab8ea433fbfbff8e11f6253b44e26256de4f94;hb=5573dd409e834ec676570cbb4b00a217cb4464b9;hp=aeff40bd78275707a895de14d4bde164fc78ce7e;hpb=fc6b583627d21a26de8268df800fd44fbb9ac30d;p=mdref%2Fmdref diff --git a/mdref/ExceptionHandler.php b/mdref/ExceptionHandler.php index aeff40b..eaab8ea 100644 --- a/mdref/ExceptionHandler.php +++ b/mdref/ExceptionHandler.php @@ -2,32 +2,72 @@ namespace mdref; -use http\Env as HTTP; +use http\Env; +use function debug_print_backtrace; +use function error_get_last; +use function headers_sent; +use function implode; +use function ob_end_clean; +use function ob_get_clean; +use function ob_get_level; +use function ob_start; +use function register_shutdown_function; +use function set_error_handler; +use function set_exception_handler; +use function sprintf; +use const E_COMPILE_ERROR; +use const E_CORE_ERROR; +use const E_ERROR; +use const E_PARSE; +use const E_USER_ERROR; /** * Exception and error handler */ class ExceptionHandler { + /** + * @var \http\Env\Response + */ + private $response; + /** * Set up error/exception/shutdown handler + * @param Env\Response $r */ - public function __construct() { + public function __construct(Env\Response $r) { + $this->response = $r; set_exception_handler($this); set_error_handler($this); register_shutdown_function($this); } - + + /** + * Clean output buffers + */ + private static function cleanBuffers() : void { + while (ob_get_level()) { + if (!@ob_end_clean()) { + break; + } + } + } + /** * The exception/error/shutdown handler callback + * + * @param \Throwable|string $e + * @param ?string $msg + * @throws \Exception */ - public function __invoke($e = null, $msg = null) { - if ($e instanceof \Exception) { + public function __invoke($e = null, ?string $msg = null) : void { + if ($e instanceof \Throwable) { try { + self::cleanBuffers(); echo static::htmlException($e); } catch (\Exception $ignore) { - headers_sent() or HTTP::setResponseCode(500); - die("FATAL ERROR"); + headers_sent() or Env::setResponseCode(500); + die("FATAL ERROR:\n$e\n$ignore"); } } elseif (isset($e, $msg)) { throw new \Exception($msg, $e); @@ -38,39 +78,33 @@ class ExceptionHandler case E_USER_ERROR: case E_CORE_ERROR: case E_COMPILE_ERROR: - while (ob_get_level()) { - if (!@ob_end_clean()) { - break; - } - } - $message = sprintf("%s in %s at line %d", + self::cleanBuffers(); + $message = sprintf("%s in %s at line %d", $error["message"], $error["file"], $error["line"]); echo static::htmlError("Application Error", $message, 500, ""); break; } } } - + /** * Format an exception as HTML and send appropriate exception info as HTTP headers - * @param \Exception $e + * @param \Throwable $e * @param array $title_tag * @param array $message_tag * @param array $trace_tag * @return string */ - public static function htmlException(\Exception $e, array $title_tag = ["h1"], array $message_tag = ["p"], array $trace_tag = ["pre", "style='font-size:smaller;overflow-x:scroll'"]) { + public static function htmlException(\Throwable $e, array $title_tag = ["h1"], array $message_tag = ["p"], + array $trace_tag = ["pre", "style='font-size:smaller;overflow-x:scroll'"]) : string { if ($e instanceof Exception) { $code = $e->getCode() ?: 500; - foreach ($e->getHeaders() as $key => $val) { - HTTP::setResponseHeader($key, $val); - } } else { $code = 500; } for ($html = ""; $e; $e = $e->getPrevious()) { - $html .= static::htmlError(HTTP::getResponseStatusForCode($code), + $html .= static::htmlError(Env::getResponseStatusForCode($code), $e->getMessage(), $code, $e->getTraceAsString(), $title_tag, $message_tag, $trace_tag); } @@ -88,8 +122,9 @@ class ExceptionHandler * @param array $trace_tag * @return string */ - public static function htmlError($title, $message, $code, $trace = null, array $title_tag = ["h1"], array $message_tag = ["p"], array $trace_tag = ["pre", "style='font-size:smaller;overflow-x:scroll'"]) { - HTTP::setResponseCode($code); + public static function htmlError($title, $message, $code, $trace = null, array $title_tag = ["h1"], + array $message_tag = ["p"], array $trace_tag = ["pre", "style='font-size:smaller;overflow-x:scroll'"]) : string { + Env::setResponseCode($code); $html = sprintf("<%s>%s\n<%s>%s\n", implode(" ", $title_tag), $title, $title_tag[0],