You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
9.3 KiB

11 years ago
13 years ago
13 years ago
11 years ago
13 years ago
11 years ago
11 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
11 years ago
13 years ago
11 years ago
11 years ago
13 years ago
13 years ago
11 years ago
13 years ago
  1. <?php namespace Majestic\Exception;
  2. /**
  3. * @copyright NetMonsters <team@netmonsters.ru>
  4. * @link http://netmonsters.ru
  5. * @package Majestic
  6. * @subpackage exception
  7. * @since 2010-02-26
  8. */
  9. class ErrorHandler
  10. {
  11. static public function init()
  12. {
  13. set_error_handler(array('Majestic\Exception\ErrorHandler', 'error_handler'));
  14. }
  15. static public function error_handler($errno, $errstr, $errfile, $errline)
  16. {
  17. $ob_handlers = ob_get_status();
  18. if (!empty($ob_handlers)) {
  19. ob_end_clean();
  20. }
  21. if (error_reporting() !== 0) {
  22. throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
  23. }
  24. return true;
  25. }
  26. static public function logError($exception)
  27. {
  28. $error = 0;
  29. $exception_name = '';
  30. if ($exception instanceof \ErrorException) {
  31. $error = $exception->getSeverity();
  32. } else {
  33. $exception_name = get_class($exception) . ': ';
  34. }
  35. switch ($error) {
  36. case E_NOTICE:
  37. $error = 'Notice';
  38. break;
  39. case E_WARNING:
  40. $error = 'Warning';
  41. break;
  42. case E_ERROR:
  43. $error = 'Fatal Error';
  44. break;
  45. default:
  46. $error = 'Unknown Error';
  47. break;
  48. }
  49. $message = 'PHP ' . $error . ': ' . $exception_name . $exception->getMessage() . ' in ' . $exception->getFile() . ':' . $exception->getLine() . ' \nStack trace:\n' . $exception->getTraceAsString() . self::getHTTPErrorConditions();
  50. // 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
  51. error_log($message);
  52. }
  53. static public function getHTTPErrorConditions()
  54. {
  55. $text = null;
  56. if (!is_null(\Majestic\Env::Server('REQUEST_METHOD')) && !is_null(\Majestic\Env::Server('REQUEST_URI'))) {
  57. $text = ', URL: ' . \Majestic\Env::Server('REQUEST_METHOD') . ' ' . \Majestic\Env::Server('REQUEST_URI');
  58. $text .= ', referrer: ' . \Majestic\Env::Server('HTTP_REFERER');
  59. }
  60. return $text;
  61. }
  62. static protected function getSource($file, $hiline)
  63. {
  64. $code = array();
  65. $i = 0;
  66. foreach (file($file) as $line) {
  67. $i++;
  68. if ($i >= $hiline - 10 && $i <= $hiline + 10) {
  69. if ($i == $hiline) {
  70. $code[] = '<tr class="error"><th>' . $i . '</th><td><span class="specific">' . htmlentities($line, ENT_QUOTES, 'UTF-8') . '</span></td></tr>';
  71. } else {
  72. $code[] = '<tr><th>' . $i . '</th><td>' . htmlentities($line, ENT_QUOTES, 'UTF-8') . '</td></tr>';
  73. }
  74. }
  75. if ($i > $hiline + 10) {
  76. break;
  77. }
  78. }
  79. return implode('', $code);
  80. }
  81. static protected function wrapArray($array, $name)
  82. {
  83. if (!$array) {
  84. return '<p>No ' . $name . ' data</p>';
  85. }
  86. $text = '<table class="req"><thead><tr><th>Variable</th><th>Value</th></tr></thead><tbody>';
  87. foreach ($array as $key => $value) {
  88. if (is_array($value) || is_object($value)) {
  89. $value = print_r($value, true);
  90. }
  91. $value = ($value) ? htmlentities($value, ENT_QUOTES, 'UTF-8') : '&nbsp;';
  92. $text .= '<tr><td>' . $key . '</td><td class="code"><div>' . $value . '</div></td></tr>';
  93. }
  94. $text .= '</tbody></table>';
  95. return $text;
  96. }
  97. static protected function wrapTrace($trace)
  98. {
  99. return '<code>' . nl2br($trace) . '</code>';
  100. }
  101. /**
  102. * @param \Exception $exception
  103. * @return string
  104. */
  105. static public function showDebug($exception)
  106. {
  107. $ob_handlers = ob_get_status();
  108. if (!empty($ob_handlers)) {
  109. ob_end_clean();
  110. }
  111. $class = get_class($exception);
  112. $method = \Majestic\Env::Server('REQUEST_METHOD', '');
  113. $uri = \Majestic\Env::getRequestUri();
  114. $source = self::getSource($exception->getFile(), $exception->getLine());
  115. $time = date('r', \Majestic\Env::Server('REQUEST_TIME', time()));
  116. $trace = nl2br($exception->getTraceAsString());
  117. $get = self::wrapArray(\Majestic\Env::Get(), 'GET');
  118. $post = self::wrapArray(\Majestic\Env::Post(), 'POST');
  119. $session = self::wrapArray(\Majestic\Session\Session::get(), 'SESSION');
  120. $files = self::wrapArray(\Majestic\Env::Files(), 'FILES');
  121. $cookies = self::wrapArray(\Majestic\Env::Cookie(), 'COOKIE');
  122. $server = self::wrapArray(\Majestic\Env::Server(), 'SERVER');
  123. $message = <<<EOD
  124. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  125. <html xmlns="http://www.w3.org/1999/xhtml">
  126. <head>
  127. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  128. <title>{$class} at {$uri}</title>
  129. <style type="text/css">
  130. html * { padding:0; margin:0; }
  131. body * { padding:10px 20px; }
  132. body * * { padding:0; }
  133. body { font:small sans-serif; }
  134. body>div { border-bottom:1px solid #ddd; }
  135. h1 { font-weight:normal; }
  136. h2 { margin-bottom:.8em; }
  137. h2 span { font-size:80%; color:#666; font-weight:normal; }
  138. h3 { margin:1em 0 .5em 0; }
  139. h4 { margin:0 0 .5em 0; font-weight: normal; }
  140. table { border:1px solid #ccc; border-collapse: collapse; width:100%; background:white; }
  141. tbody td, tbody th { vertical-align:top; padding:2px 3px; }
  142. thead th { padding:1px 6px 1px 3px; background:#fefefe; text-align:left; font-weight:normal; font-size:11px; border:1px solid #ddd; }
  143. tbody th { width:12em; text-align:right; color:#666; padding-right:.5em; }
  144. table.vars { margin:5px 0 2px 40px; }
  145. table.vars td, table.req td { font-family:monospace; }
  146. table td.code { width:100%; }
  147. table td.code div { overflow:hidden; }
  148. table.source th { color:#666; }
  149. table.source td { font-family:monospace; white-space:pre; border-bottom:1px solid #eee; }
  150. ul.traceback { list-style-type:none; }
  151. ul.traceback li.frame { margin-bottom:1em; }
  152. div.context { margin: 10px 0; }
  153. div.context ol { padding-left:30px; margin:0 10px; list-style-position: inside; }
  154. div.context ol li { font-family:monospace; white-space:pre; color:#666; cursor:pointer; }
  155. div.context ol.context-line li { color:black; background-color:#ccc; }
  156. div.context ol.context-line li span { float: right; }
  157. div.commands { margin-left: 40px; }
  158. div.commands a { color:black; text-decoration:none; }
  159. #summary { background: #ffc; }
  160. #summary h2 { font-weight: normal; color: #666; }
  161. #explanation { background:#eee; }
  162. #source{ background:#f6f6f6; }
  163. #traceback { background:#eee; }
  164. #requestinfo { background:#f6f6f6; padding-left:120px; }
  165. #summary table { border:none; background:transparent; }
  166. #requestinfo h2, #requestinfo h3 { position:relative; margin-left:-100px; }
  167. #requestinfo h3 { margin-bottom:-1em; }
  168. .error { background: #ffc; }
  169. .specific { color:#cc3300; font-weight:bold; }
  170. h2 span.commands { font-size:.7em;}
  171. span.commands a:link {color:#5E5694;}
  172. pre.exception_value { font-family: sans-serif; color: #666; font-size: 1.5em; margin: 10px 0 10px 0; }
  173. </style>
  174. </head>
  175. <body>
  176. <div id="summary">
  177. <h1>{$class} at {$uri}</h1>
  178. <pre class="exception_value">{$exception->getMessage()}</pre>
  179. <table class="meta">
  180. <tbody>
  181. <tr><th>Request Method:</th><td>{$method}</td></tr>
  182. <tr><th>Exception Type:</th><td>{$class}</td></tr>
  183. <tr><th>Exception Message:</th><td><pre>{$exception->getMessage()}</pre></td></tr>
  184. <tr><th>Exception Location:</th><td>{$exception->getFile()}, line {$exception->getLine()}</td></tr>
  185. <tr><th>Server time:</th><td>{$time}</td></tr>
  186. </tbody>
  187. </table>
  188. </div>
  189. <div id="source">
  190. <h2>Context</h2>
  191. <p>In file <code>{$exception->getFile()}</code>, error at line <strong>{$exception->getLine()}</strong></p>
  192. <h3>{$exception->getMessage()}</h3>
  193. <table class="source cut-top">
  194. <tbody>{$source}</tbody>
  195. </table>
  196. </div>
  197. <div id="traceback">
  198. <h2>Traceback</h2>
  199. <div id="browserTraceback"><code>{$trace}</code></div>
  200. </div>
  201. <div id="requestinfo">
  202. <h2>Request information</h2>
  203. <h3 id="get-info">GET</h3>
  204. {$get}
  205. <h3 id="post-info">POST</h3>
  206. {$post}
  207. <h3 id="session-info">SESSION</h3>
  208. {$session}
  209. <h3 id="files-info">FILES</h3>
  210. {$files}
  211. <h3 id="cookie-info">COOKIES</h3>
  212. {$cookies}
  213. <h3 id="meta-info">SERVER</h3>
  214. {$server}
  215. <h3 id="settings-info">Settings</h3>
  216. <p>todo</p>
  217. </div>
  218. <div id="explanation">
  219. <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>
  220. </div>
  221. </body>
  222. </html>
  223. EOD;
  224. return $message;
  225. }
  226. }