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