Browse Source
Errors and exceptions handling, #16
Errors and exceptions handling, #16
git-svn-id: svn+ssh://code.netmonsters.ru/svn/majestic/branches/evo@121 4cb57b5f-5bbd-dd11-951b-001d605cbbc5master
pzinovkin
15 years ago
7 changed files with 305 additions and 82 deletions
-
59app/ErrorAction.php
-
36app/FrontController.php
-
34classes/Env.class.php
-
13exception/Error404Exception.php
-
190exception/ErrorHandler.php
-
19exception/GeneralException.php
-
10view/PHPView.php
@ -0,0 +1,59 @@ |
|||
<?php |
|||
/** |
|||
* @copyright NetMonsters <team@netmonsters.ru> |
|||
* @link http://netmonsters.ru |
|||
* @package Majestic |
|||
* @subpackage app |
|||
* @since 2010-02-25 |
|||
* @version SVN: $Id$ |
|||
* @filesource $URL$ |
|||
*/ |
|||
|
|||
class ErrorAction extends ViewAction |
|||
{ |
|||
|
|||
/** |
|||
* @var Exception |
|||
*/ |
|||
protected $exception; |
|||
|
|||
public function __construct($exception) |
|||
{ |
|||
$this->exception = $exception; |
|||
$this->view = FrontController::getInstance()->getView(); |
|||
$this->execute(); |
|||
} |
|||
|
|||
protected function execute() |
|||
{ |
|||
$this->template = 500; |
|||
if ($this->exception instanceof Error404Exception) { |
|||
$this->template = 404; |
|||
} |
|||
} |
|||
|
|||
protected function getTemplate() |
|||
{ |
|||
return '/static/' . $this->template; |
|||
} |
|||
|
|||
protected function sendHttpCode($code) |
|||
{ |
|||
if (headers_sent()) { |
|||
return; |
|||
} |
|||
switch ($code) { |
|||
case 404: |
|||
header('HTTP/1.0 404 Not Found'); |
|||
break; |
|||
default: |
|||
header('HTTP/1.0 500 Internal Server Error'); |
|||
} |
|||
} |
|||
|
|||
public function fetch() |
|||
{ |
|||
$this->sendHTTPCode($this->template); |
|||
return $this->view->fetch($this->getTemplate()); |
|||
} |
|||
} |
@ -0,0 +1,190 @@ |
|||
<?php |
|||
/** |
|||
* @copyright NetMonsters <team@netmonsters.ru> |
|||
* @link http://netmonsters.ru |
|||
* @package Majestic |
|||
* @subpackage exception |
|||
* @since 2010-02-26 |
|||
* @version SVN: $Id$ |
|||
* @filesource $URL$ |
|||
*/ |
|||
|
|||
class ErrorHandler |
|||
{ |
|||
|
|||
static public function init() |
|||
{ |
|||
set_error_handler(array('ErrorHandler', 'error_handler')); |
|||
} |
|||
|
|||
static public function error_handler($errno, $errstr, $errfile, $errline ) |
|||
{ |
|||
throw new ErrorException($errstr, 0, $errno, $errfile, $errline); |
|||
return false; |
|||
} |
|||
|
|||
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">' . $line . '</span></td></tr>'; |
|||
}else{ |
|||
$code[] = '<tr><th>' . $i . '</th><td>' . $line . '</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) { |
|||
$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 |
|||
*/ |
|||
static public function showDebug($exception) |
|||
{ |
|||
$class = get_class($exception); |
|||
|
|||
$method = Env::Server('REQUEST_METHOD', ''); |
|||
$uri = Env::getRequestUri(); |
|||
$source = self::getSource($exception->getFile(), $exception->getLine()); |
|||
$time = date('r', Env::Server('REQUEST_TIME', time())); |
|||
|
|||
$trace = self::wrapTrace($exception->getTraceAsString()); |
|||
|
|||
$get = self::wrapArray(Env::Get(), 'GET'); |
|||
$post = self::wrapArray(Env::Post(), 'POST'); |
|||
$files = self::wrapArray(Env::Files(), 'FILES'); |
|||
$cookies = self::wrapArray(Env::Cookie(), 'COOKIE'); |
|||
$server = self::wrapArray(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> |
|||
<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">{$trace}</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="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; |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue