xref: /dokuwiki/inc/ErrorHandler.php (revision 642e976cb685105e1684f43a5d99c79f258029f4)
1<?php
2
3namespace dokuwiki;
4
5class ErrorHandler
6{
7
8    /**
9     * Register the default error handling
10     */
11    public static function register()
12    {
13        set_error_handler([ErrorHandler::class, 'errorConverter']);
14        if (!defined('DOKU_UNITTEST')) {
15            set_exception_handler([ErrorHandler::class, 'fatalException']);
16        }
17    }
18
19    /**
20     * Default Exception handler to show a nice user message before dieing
21     *
22     * The exception is logged to the error log
23     *
24     * @param \Throwable $e
25     */
26    public static function fatalException($e)
27    {
28        $title = hsc(get_class($e) . ': ' . $e->getMessage());
29        $msg = 'An unforeseen error has occured. This is most likely a bug somewhere.';
30        $logged = self::logException($e)
31            ? 'More info has been written to the DokuWiki _error.log'
32            : $e->getFile() . ':' . $e->getLine();
33
34        echo <<<EOT
35<!DOCTYPE html>
36<html>
37<head><title>$title</title></head>
38<body style="font-family: Arial, sans-serif">
39    <div style="width:60%; margin: auto; background-color: #fcc;
40                border: 1px solid #faa; padding: 0.5em 1em;">
41        <h1 style="font-size: 120%">$title</h1>
42        <p>$msg</p>
43        <p>$logged</p>
44    </div>
45</body>
46</html>
47EOT;
48    }
49
50    /**
51     * Convenience method to display an error message for the given Exception
52     *
53     * @param \Throwable $e
54     * @param string $intro
55     */
56    public static function showExceptionMsg($e, $intro = 'Error!')
57    {
58        $msg = $intro . get_class($e) . ': ' . $e->getMessage();
59        self::logException($e);
60        msg(hsc($msg), -1);
61    }
62
63    /**
64     * Default error handler to convert old school warnings, notices, etc to exceptions
65     *
66     * You should not need to call this directly!
67     *
68     * @param int $errno
69     * @param string $errstr
70     * @param string $errfile
71     * @param int $errline
72     * @return bool
73     * @throws \ErrorException
74     */
75    public static function errorConverter($errno, $errstr, $errfile, $errline)
76    {
77        if (!(error_reporting() & $errno)) {
78            // This error code is not included in error_reporting, so let it fall
79            // through to the standard PHP error handler
80            return false;
81        }
82        throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
83    }
84
85    /**
86     * Log the given exception to the error log
87     *
88     * @param \Throwable $e
89     * @return bool false if the logging failed
90     */
91    public static function logException($e)
92    {
93        global $conf;
94
95        $log = join("\t", [gmdate('c'), get_class($e), $e->getFile() . ':' . $e->getLine(), $e->getMessage()]) . "\n";
96        return io_saveFile($conf['cachedir'] . '/_error.log', $log, true);
97    }
98}
99