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