PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/RackTables-0.19.12/wwwroot/inc/exceptions.php

#
PHP | 282 lines | 248 code | 17 blank | 17 comment | 11 complexity | 452172d510c9b20fc11e3a21b4b0756a MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0
  1. <?php
  2. # This file is a part of RackTables, a datacenter and server room management
  3. # framework. See accompanying file "COPYING" for the full copyright and
  4. # licensing information.
  5. // The default approach is to treat an error as fatal, in which case
  6. // some message is output and the user is left there. Inheriting classes
  7. // represent more specific cases, some of which can be handled in a
  8. // "softer" way (see below).
  9. class RackTablesError extends Exception
  10. {
  11. const INTERNAL = 2;
  12. const DB_WRITE_FAILED = 3;
  13. const NOT_AUTHENTICATED = 4;
  14. const MISCONFIGURED = 6;
  15. protected final function genHTMLPage ($title, $text)
  16. {
  17. global $helpdesk_banner;
  18. header ('Content-Type: text/html; charset=UTF-8');
  19. echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'."\n";
  20. echo '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'."\n";
  21. echo "<head><title>${title}</title>";
  22. echo "</head><body>${text}";
  23. if (isset ($helpdesk_banner))
  24. echo '<hr>' . $helpdesk_banner;
  25. echo '</body></html>';
  26. }
  27. public function dispatch()
  28. {
  29. $msgheader = array
  30. (
  31. self::NOT_AUTHENTICATED => 'Not authenticated',
  32. self::MISCONFIGURED => 'Configuration error',
  33. self::INTERNAL => 'Internal error',
  34. self::DB_WRITE_FAILED => 'Database write failed',
  35. );
  36. $msgbody = array
  37. (
  38. self::NOT_AUTHENTICATED => '<h2>This system requires authentication. You should use a username and a password.</h2>',
  39. self::MISCONFIGURED => '<h2>Configuration error</h2><br>' . $this->message,
  40. self::INTERNAL => '<h2>Internal error</h2><br>' . $this->message,
  41. self::DB_WRITE_FAILED => '<h2>Database write failed</h2><br>' . $this->message,
  42. );
  43. switch ($this->code)
  44. {
  45. case self::NOT_AUTHENTICATED:
  46. header ('WWW-Authenticate: Basic realm="' . getConfigVar ('enterprise') . ' RackTables access"');
  47. header ("HTTP/1.1 401 Unauthorized");
  48. case self::MISCONFIGURED:
  49. case self::INTERNAL:
  50. case self::DB_WRITE_FAILED:
  51. $this->genHTMLPage ($msgheader[$this->code], $msgbody[$this->code]);
  52. break;
  53. default:
  54. throw new RackTablesError ('Dispatching error, unknown code ' . $this->code, RackTablesError::INTERNAL);
  55. }
  56. }
  57. }
  58. // this simplifies construction of RackTablesError, but is never caught
  59. class EntityNotFoundException extends RackTablesError
  60. {
  61. function __construct($entity, $id)
  62. {
  63. parent::__construct ("Object '$entity'#'$id' does not exist");
  64. }
  65. public function dispatch()
  66. {
  67. RackTablesError::genHTMLPage ('Missing record', "<h2>Missing record</h2><br>" . $this->message);
  68. }
  69. }
  70. // this simplifies construction of RackTablesError, but is never caught
  71. class InvalidArgException extends RackTablesError
  72. {
  73. function __construct ($name, $value, $reason=NULL)
  74. {
  75. $message = "Argument '${name}' of value '".var_export($value,true)."' is invalid.";
  76. if (!is_null($reason))
  77. $message .= ' ('.$reason.')';
  78. parent::__construct ($message, parent::INTERNAL);
  79. }
  80. }
  81. // this simplifies construction and helps in catching "soft"
  82. // errors (invalid input from the user)
  83. class InvalidRequestArgException extends RackTablesError
  84. {
  85. function __construct ($name, $value, $reason=NULL)
  86. {
  87. $message = "Argument '${name}' of value " . var_export ($value, TRUE) . " is invalid";
  88. if (!is_null($reason))
  89. $message .= ' ('.$reason.')';
  90. $message .= '.';
  91. parent::__construct ($message);
  92. }
  93. public function dispatch()
  94. {
  95. RackTablesError::genHTMLPage ('Assertion failed', '<h2>Assertion failed</h2><br>' . $this->message);
  96. }
  97. }
  98. // this wraps certain known PDO errors and is caught in process.php
  99. // as a "soft" error
  100. class RTDatabaseError extends RackTablesError
  101. {
  102. public function dispatch()
  103. {
  104. RackTablesError::genHTMLPage ('Database soft error', '<h2>Database soft error</h2><br>' . $this->message);
  105. }
  106. }
  107. // gateway failure is a common case of a "soft" error, some functions do catch this
  108. class RTGatewayError extends RackTablesError
  109. {
  110. public function dispatch()
  111. {
  112. RackTablesError::genHTMLPage ('Gateway error', '<h2>Gateway error</h2><br>' . $this->message);
  113. }
  114. }
  115. class RTBuildLVSConfigError extends RackTablesError
  116. {
  117. public $message_list;
  118. public $config_to_display;
  119. public $balancer_id;
  120. function __construct($message_list, $config_to_display, $object_id) {
  121. $this->code = parent::INTERNAL;
  122. $this->message_list = $message_list;
  123. $this->config_to_display = $config_to_display;
  124. $this->balancer_id = $object_id;
  125. parent::__construct("LVS config build error for balancer $object_id: " . implode("\n", $message_list));
  126. }
  127. public function dispatch()
  128. {
  129. // redirect user to a page with config errors highlighted
  130. header ("Location: index.php?page=object&tab=lvsconfig&object_id=" . urlencode ($this->balancer_id));
  131. die;
  132. }
  133. }
  134. # "Permission denied" is a very common case, which in some situations is
  135. # treated as a "soft" error.
  136. class RTPermissionDenied extends RackTablesError
  137. {
  138. public function dispatch()
  139. {
  140. header ('Content-Type: text/html; charset=UTF-8');
  141. echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'."\n";
  142. echo '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'."\n";
  143. echo "<head><title>RackTables: access denied</title>\n";
  144. printPageHeaders();
  145. echo "</head><body>";
  146. global $pageno, $tabno,
  147. $user_given_tags,
  148. $target_given_tags,
  149. $auto_tags,
  150. $expl_tags,
  151. $impl_tags;
  152. echo "<table border=1 cellspacing=0 cellpadding=3 width='50%' align=center>\n";
  153. echo '<tr><th colspan=2><h3>' . getImageHREF ('DENIED') . ' access denied ';
  154. echo getImageHREF ('DENIED') . '</h3></th></tr>';
  155. echo "<tr><th width='50%' class=tagchain>User given tags:</th><td class=tagchain>";
  156. echo serializeTags ($user_given_tags) . "&nbsp;</td></tr>\n";
  157. echo "<tr><th width='50%' class=tagchain>Target given tags:</th><td class=tagchain>";
  158. echo serializeTags ($target_given_tags) . "&nbsp;</td></tr>\n";
  159. echo "<tr><th width='50%' class=tagchain>Effective explicit tags:</th><td class=tagchain>";
  160. echo serializeTags ($expl_tags) . "&nbsp;</td></tr>\n";
  161. echo "<tr><th width='50%' class=tagchain>Effective implicit tags:</th><td class=tagchain>";
  162. echo serializeTags ($impl_tags) . "&nbsp;</td></tr>\n";
  163. echo "<tr><th width='50%' class=tagchain>Automatic tags:</th><td class=tagchain>";
  164. echo serializeTags ($auto_tags) . "&nbsp;</td></tr>\n";
  165. echo "<tr><th width='50%' class=tdright>Requested page:</th><td class=tdleft>${pageno}</td></tr>\n";
  166. echo "<tr><th width='50%' class=tdright>Requested tab:</th><td class=tdleft>${tabno}</td></tr>\n";
  167. echo "<tr><td colspan=2 align=center>Click <a href='index.php?logout'>here</a> to logout.</td></tr>\n";
  168. echo "</table>\n";
  169. echo "</body></html>";
  170. }
  171. }
  172. function dumpArray($arr)
  173. {
  174. echo '<table class="exceptionParametersDump">';
  175. foreach($arr as $key=>$value)
  176. {
  177. echo "<tr><th>$key</th><td>$value</td></tr>";
  178. }
  179. echo '</table>';
  180. }
  181. function stringTrace($trace)
  182. {
  183. $ret = '';
  184. foreach($trace as $line) {
  185. if (isset ($line['file']) && isset ($line['line']))
  186. $ret .= $line['file'].':'.$line['line'].' ';
  187. $ret .= $line['function'].'(';
  188. $f = true;
  189. if (isset($line['args']) and is_array($line['args'])) foreach ($line['args'] as $arg) {
  190. if (!$f) $ret .= ', ';
  191. if (is_string($arg))
  192. $printarg = "'".$arg."'";
  193. elseif (is_null($arg))
  194. $printarg = 'NULL';
  195. elseif (is_array($arg))
  196. $printarg = print_r($arg, 1);
  197. else
  198. $printarg = $arg;
  199. $ret .= $printarg;
  200. $f = false;
  201. }
  202. $ret .= ")\n";
  203. }
  204. return $ret;
  205. }
  206. function printPDOException($e)
  207. {
  208. header("HTTP/1.1 500 Internal Server Error");
  209. header ('Content-Type: text/html; charset=UTF-8');
  210. echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'."\n";
  211. echo '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'."\n";
  212. echo "<head><title> PDO Exception </title>\n";
  213. echo "<link rel=stylesheet type='text/css' href='?module=chrome&uri=css/pi.css' />\n";
  214. echo "<link rel=icon href='?module=chrome&uri=pix/favicon.ico' type='image/x-icon' />\n";
  215. echo '</head> <body>';
  216. echo '<h2>Pdo exception: '.get_class($e).'</h2><code>'.$e->getMessage().'</code> (<code>'.$e->getCode().'</code>)';
  217. echo '<p>at file <code>'.$e->getFile().'</code>, line <code>'.$e->getLine().'</code></p><pre>';
  218. echo stringTrace($e->getTrace());
  219. echo '</pre>';
  220. echo '<h2>Error info:</h2>';
  221. echo '<pre>';
  222. print_r($e->errorInfo);
  223. echo '</pre>';
  224. echo '<h2>Parameters:</h2>';
  225. echo '<h3>GET</h3>';
  226. dumpArray($_GET);
  227. echo '<h3>POST</h3>';
  228. dumpArray($_POST);
  229. echo '<h3>COOKIE</h3>';
  230. dumpArray($_COOKIE);
  231. echo '</body></html>';
  232. }
  233. function printGenericException($e)
  234. {
  235. header("HTTP/1.1 500 Internal Server Error");
  236. header ('Content-Type: text/html; charset=UTF-8');
  237. echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'."\n";
  238. echo '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'."\n";
  239. echo "<head><title> Exception </title>\n";
  240. echo "<link rel=stylesheet type='text/css' href='?module=chrome&uri=css/pi.css' />\n";
  241. echo "<link rel=icon href='?module=chrome&uri=pix/favicon.ico' type='image/x-icon' />\n";
  242. echo '</head> <body>';
  243. echo '<h2>Uncaught exception: '.get_class($e).'</h2><code>'.$e->getMessage().'</code> (<code>'.$e->getCode().'</code>)';
  244. echo '<p>at file <code>'.$e->getFile().'</code>, line <code>'.$e->getLine().'</code></p><pre>';
  245. echo stringTrace($e->getTrace());
  246. echo '</pre>';
  247. echo '<h2>Parameters:</h2>';
  248. echo '<h3>GET</h3>';
  249. dumpArray($_GET);
  250. echo '<h3>POST</h3>';
  251. dumpArray($_POST);
  252. echo '<h3>COOKIE</h3>';
  253. dumpArray($_COOKIE);
  254. echo '</body></html>';
  255. }
  256. function printException($e)
  257. {
  258. if ($e instanceof RackTablesError)
  259. $e->dispatch();
  260. elseif ($e instanceof PDOException)
  261. printPDOException($e);
  262. else
  263. printGenericException($e);
  264. }
  265. ?>