dunno my own method names...
[mdref/mdref] / mdref / ExceptionHandler.php
1 <?php
2
3 namespace mdref;
4
5 use http\Env as HTTP;
6
7 /**
8 * mdref exception handler
9 */
10 class ExceptionHandler
11 {
12 function __construct() {
13 set_exception_handler($this);
14 set_error_handler($this);
15 }
16
17 function __invoke($e, $msg = null) {
18 if ($e instanceof \Exception) {
19 try {
20 echo static::html($e);
21 } catch (\Exception $ignore) {
22 headers_sent() or HTTP::setResponseCode(500);
23 }
24 } else {
25 throw new \Exception($msg, $e);
26 }
27 return true;
28 }
29
30 /**
31 * Format an exception as HTML and send appropriate exception info as HTTP headers
32 * @param \Exception $e
33 * @param array $title_tag
34 * @param array $message_tag
35 * @param array $trace_tag
36 * @return string
37 */
38 static function html(\Exception $e, array $title_tag = ["h1"], array $message_tag = ["p"], array $trace_tag = ["pre", "style='font-size:smaller'"]) {
39 if ($e instanceof \http\Controller\Exception) {
40 $code = $e->getCode() ?: 500;
41 foreach ($e->getHeaders() as $key => $val) {
42 HTTP::setResponseHeader($key, $val);
43 }
44 } else {
45 $code = 500;
46 }
47 HTTP::setResponseCode($code);
48 $name = HTTP::getResponseStatusForCode($code);
49 $html = sprintf("<%s>%s</%s>\n<%s>%s</%s>\n",
50 implode(" ", $title_tag), $name, $title_tag[0],
51 implode(" ", $message_tag), $e->getMessage(), $message_tag[0]);
52 if ($trace_tag) {
53 $html .= sprintf("<%s>%s</%s>\n",
54 implode(" ", $trace_tag), $e->getTraceAsString(), $trace_tag[0]);
55 }
56 return $html;
57 }
58 }