|
|
<?php namespace Majestic\Exception; /** * @copyright NetMonsters <team@netmonsters.ru> * @link http://netmonsters.ru * @package Majestic * @subpackage exception * @since 2010-02-26 */
class ErrorHandler {
static public function init() { set_error_handler(array('Majestic\Exception\ErrorHandler', 'error_handler')); }
static public function error_handler($errno, $errstr, $errfile, $errline) { $ob_handlers = ob_get_status(); if (!empty($ob_handlers)) { ob_end_clean(); } if (error_reporting() !== 0) { throw new \ErrorException($errstr, 0, $errno, $errfile, $errline); } return true; }
static public function logError($exception) { $error = 0; $exception_name = ''; if ($exception instanceof \ErrorException) { $error = $exception->getSeverity(); } else { $exception_name = get_class($exception) . ': '; }
switch ($error) { case E_NOTICE: $error = 'Notice'; break; case E_WARNING: $error = 'Warning'; break; case E_ERROR: $error = 'Fatal Error'; break; default: $error = 'Unknown Error'; break; } $message = 'PHP ' . $error . ': ' . $exception_name . $exception->getMessage() . ' in ' . $exception->getFile() . ':' . $exception->getLine() . ' \nStack trace:\n' . $exception->getTraceAsString() . self::getHTTPErrorConditions(); // PHP Fatal error: Uncaught exception 'LogicException' in /www/test.tfs/face/htdocs/index.php:11\nStack trace:\n#0 {main}\n thrown in /www/test.tfs/face/htdocs/index.php on line 11, referer: http://test.tfs.manekeno.netmonsters.ru/news/create
error_log($message); }
static public function getHTTPErrorConditions() { $text = null; if (!is_null(\Majestic\Env::Server('REQUEST_METHOD')) && !is_null(\Majestic\Env::Server('REQUEST_URI'))) { $text = ', URL: ' . \Majestic\Env::Server('REQUEST_METHOD') . ' ' . \Majestic\Env::Server('REQUEST_URI'); $text .= ', referrer: ' . \Majestic\Env::Server('HTTP_REFERER'); } return $text; }
static protected function getSource($file, $hiline) { $code = array(); $i = 0; foreach (file($file) as $line) { $i++; if ($i >= $hiline - 10 && $i <= $hiline + 10) { if ($i == $hiline) { $code[] = '<tr class="error"><th>' . $i . '</th><td><span class="specific">' . htmlentities($line, ENT_QUOTES, 'UTF-8') . '</span></td></tr>'; } else { $code[] = '<tr><th>' . $i . '</th><td>' . htmlentities($line, ENT_QUOTES, 'UTF-8') . '</td></tr>'; } } if ($i > $hiline + 10) { break; } } return implode('', $code); }
static protected function wrapArray($array, $name) { if (!$array) { return '<p>No ' . $name . ' data</p>'; } $text = '<table class="req"><thead><tr><th>Variable</th><th>Value</th></tr></thead><tbody>'; foreach ($array as $key => $value) { if (is_array($value) || is_object($value)) { $value = print_r($value, true); } $value = ($value) ? htmlentities($value, ENT_QUOTES, 'UTF-8') : ' '; $text .= '<tr><td>' . $key . '</td><td class="code"><div>' . $value . '</div></td></tr>'; } $text .= '</tbody></table>'; return $text; }
static protected function wrapTrace($trace) { return '<code>' . nl2br($trace) . '</code>'; }
/** * @param \Exception $exception * @return string */ static public function showDebug($exception) { $ob_handlers = ob_get_status(); if (!empty($ob_handlers)) { ob_end_clean(); } $class = get_class($exception);
$method = \Majestic\Env::Server('REQUEST_METHOD', ''); $uri = \Majestic\Env::getRequestUri(); $source = self::getSource($exception->getFile(), $exception->getLine()); $time = date('r', \Majestic\Env::Server('REQUEST_TIME', time()));
$trace = nl2br($exception->getTraceAsString());
$get = self::wrapArray(\Majestic\Env::Get(), 'GET'); $post = self::wrapArray(\Majestic\Env::Post(), 'POST'); $session = self::wrapArray(\Majestic\Session\Session::get(), 'SESSION'); $files = self::wrapArray(\Majestic\Env::Files(), 'FILES'); $cookies = self::wrapArray(\Majestic\Env::Cookie(), 'COOKIE'); $server = self::wrapArray(\Majestic\Env::Server(), 'SERVER');
$message = <<<EOD <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>{$class} at {$uri}</title> <style type="text/css"> html * { padding:0; margin:0; } body * { padding:10px 20px; } body * * { padding:0; } body { font:small sans-serif; } body>div { border-bottom:1px solid #ddd; }
h1 { font-weight:normal; } h2 { margin-bottom:.8em; } h2 span { font-size:80%; color:#666; font-weight:normal; }
h3 { margin:1em 0 .5em 0; } h4 { margin:0 0 .5em 0; font-weight: normal; } table { border:1px solid #ccc; border-collapse: collapse; width:100%; background:white; }
tbody td, tbody th { vertical-align:top; padding:2px 3px; } thead th { padding:1px 6px 1px 3px; background:#fefefe; text-align:left; font-weight:normal; font-size:11px; border:1px solid #ddd; }
tbody th { width:12em; text-align:right; color:#666; padding-right:.5em; }
table.vars { margin:5px 0 2px 40px; } table.vars td, table.req td { font-family:monospace; } table td.code { width:100%; } table td.code div { overflow:hidden; } table.source th { color:#666; }
table.source td { font-family:monospace; white-space:pre; border-bottom:1px solid #eee; }
ul.traceback { list-style-type:none; } ul.traceback li.frame { margin-bottom:1em; } div.context { margin: 10px 0; } div.context ol { padding-left:30px; margin:0 10px; list-style-position: inside; } div.context ol li { font-family:monospace; white-space:pre; color:#666; cursor:pointer; }
div.context ol.context-line li { color:black; background-color:#ccc; }
div.context ol.context-line li span { float: right; } div.commands { margin-left: 40px; } div.commands a { color:black; text-decoration:none; } #summary { background: #ffc; }
#summary h2 { font-weight: normal; color: #666; }
#explanation { background:#eee; }
#source{ background:#f6f6f6; }
#traceback { background:#eee; }
#requestinfo { background:#f6f6f6; padding-left:120px; }
#summary table { border:none; background:transparent; }
#requestinfo h2, #requestinfo h3 { position:relative; margin-left:-100px; }
#requestinfo h3 { margin-bottom:-1em; }
.error { background: #ffc; }
.specific { color:#cc3300; font-weight:bold; }
h2 span.commands { font-size:.7em;} span.commands a:link {color:#5E5694;}
pre.exception_value { font-family: sans-serif; color: #666; font-size: 1.5em; margin: 10px 0 10px 0; }
</style> </head> <body> <div id="summary"> <h1>{$class} at {$uri}</h1> <pre class="exception_value">{$exception->getMessage()}</pre> <table class="meta"> <tbody> <tr><th>Request Method:</th><td>{$method}</td></tr> <tr><th>Exception Type:</th><td>{$class}</td></tr> <tr><th>Exception Message:</th><td><pre>{$exception->getMessage()}</pre></td></tr> <tr><th>Exception Location:</th><td>{$exception->getFile()}, line {$exception->getLine()}</td></tr> <tr><th>Server time:</th><td>{$time}</td></tr> </tbody> </table> </div>
<div id="source"> <h2>Context</h2> <p>In file <code>{$exception->getFile()}</code>, error at line <strong>{$exception->getLine()}</strong></p> <h3>{$exception->getMessage()}</h3> <table class="source cut-top"> <tbody>{$source}</tbody> </table> </div> <div id="traceback"> <h2>Traceback</h2> <div id="browserTraceback"><code>{$trace}</code></div> </div>
<div id="requestinfo"> <h2>Request information</h2> <h3 id="get-info">GET</h3> {$get} <h3 id="post-info">POST</h3> {$post} <h3 id="session-info">SESSION</h3> {$session} <h3 id="files-info">FILES</h3> {$files} <h3 id="cookie-info">COOKIES</h3> {$cookies} <h3 id="meta-info">SERVER</h3> {$server} <h3 id="settings-info">Settings</h3> <p>todo</p> </div> <div id="explanation"> <p>You're seeing this error because you have defined constant <code>DEBUG = True</code> in your config file. Change that to <code>False</code>, and it will display a standard 500 page.</p> </div> </body> </html> EOD; return $message; } }
|