8 * Exception and error handler
10 class ExceptionHandler
13 * Set up error/exception/shutdown handler
15 public function __construct() {
16 set_exception_handler($this);
17 set_error_handler($this);
18 register_shutdown_function($this);
22 * The exception/error/shutdown handler callback
24 public function __invoke($e = null, $msg = null) {
25 if ($e instanceof \Exception
) {
27 echo static::htmlException($e);
28 } catch (\Exception
$ignore) {
29 headers_sent() or HTTP
::setResponseCode(500);
32 } elseif (isset($e, $msg)) {
33 throw new \
Exception($msg, $e);
34 } elseif (($error = error_get_last())) {
35 switch ($error["type"]) {
41 while (ob_get_level()) {
42 if (!@ob_end_clean
()) {
46 $message = sprintf("%s in %s at line %d",
47 $error["message"], $error["file"], $error["line"]);
48 echo static::htmlError("Application Error", $message, 500, "");
55 * Format an exception as HTML and send appropriate exception info as HTTP headers
56 * @param \Exception $e
57 * @param array $title_tag
58 * @param array $message_tag
59 * @param array $trace_tag
62 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'"]) {
63 if ($e instanceof Exception
) {
64 $code = $e->getCode() ?
: 500;
65 foreach ($e->getHeaders() as $key => $val) {
66 HTTP
::setResponseHeader($key, $val);
72 for ($html = ""; $e; $e = $e->getPrevious()) {
73 $html .= static::htmlError(HTTP
::getResponseStatusForCode($code),
74 $e->getMessage(), $code, $e->getTraceAsString(),
75 $title_tag, $message_tag, $trace_tag);
81 * Format an error as HTML
82 * @param string $title
83 * @param string $message
85 * @param string $trace
86 * @param array $title_tag
87 * @param array $message_tag
88 * @param array $trace_tag
91 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'"]) {
92 HTTP
::setResponseCode($code);
94 $html = sprintf("<%s>%s</%s>\n<%s>%s</%s>\n",
95 implode(" ", $title_tag), $title, $title_tag[0],
96 implode(" ", $message_tag), $message, $message_tag[0]);
100 debug_print_backtrace();
101 $trace = ob_get_clean();
103 if (!empty($trace)) {
104 $html .= sprintf("<%s>%s</%s>\n",
105 implode(" ", $trace_tag), $trace, $trace_tag[0]);