refine the use of $debug_mode
[racktables] / wwwroot / inc / exceptions.php
CommitLineData
b135a49d
DY
1<?php
2
cddbb9fd
DO
3# This file is a part of RackTables, a datacenter and server room management
4# framework. See accompanying file "COPYING" for the full copyright and
5# licensing information.
6
8d3ab47c
DO
7define
8(
9 'IMG_100x10_PBAR_ERROR', // 100x10, red on pink, "progr. bar error"
10 'iVBORw0KGgoAAAANSUhEUgAAAGQAAAAKCAYAAABCHPt+AAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A' .
11 '/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sDERYTJrBhF8sAAACvSURBVEjH' .
12 '7VdRDoAgCMXmQbz/qbhJfdnMQQiDTZ3vL6MHvEA03Yg3rIRSABBhV1xwMBXyp/JatFVYq7La1Hft' .
13 'N709xcXxWLqE4tbGr+GXdNDqw8STxSS0z9S695ZD+e05pXhHt8RRHqtebIdoRPASM2K+ePi18Gjz' .
14 'Yuwz7AKpM2cpmjPUVx3qf0OIqyLKvl+POMp6+R3Jy9oxnD4C0nsPiTrfb35viO2QiOF6foYKD57g' .
15 'f1uXQb2mAAAAAElFTkSuQmCC'
16);
17define
18(
19 'IMG_100x10_PHP_GD_NA', // 100x10, red on pink: "PHP-GD is N/A"
20 'iVBORw0KGgoAAAANSUhEUgAAAGQAAAAKCAYAAABCHPt+AAAAw0lEQVRIx+1XwQ3AIAjUxkHcfyo3' .
21 'aV8kligino2mkvRhERHOQ/R3Src7soxcv4o2xuW3GGDBpfTW5WP+T7K1+OJSW6/lR7t/zfhzQDQg' .
22 'IGwp4dJ8rkMkp2cNmgvwu0fJ4kFKQUs6ApdAo6+2Tk0HYgOeIfmGSxS32iJtLMBZmQRgSZgWVAug' .
23 'VomSmDF6OfPTL905mgQDm4XgVpNS8L31vMdPa75UurRNxtaA1BLSUx7RJzoHhXeLJRYPlC1/HoYT' .
24 'uy+DPGgNeJs7N+Q1AAAAAElFTkSuQmCC'
25);
26define
27(
28 'IMG_100x10_ARG_ERROR', // 100x10, red on pink: "argument error"
29 'iVBORw0KGgoAAAANSUhEUgAAAGQAAAAKCAYAAABCHPt+AAAApElEQVRIx+1WUQ6AIAjF1kG8/6m4' .
30 'iX2xNUYKSKnN9xc2RODxSAWxwN+RMwDiEqEesDEVzq6uI1D3tWxk5x1L30//cp/Wu+5nElM0b/G8' .
31 '18FKf0GkhNbsUsIsfnnhLPfXRpbWlzY2ZyFiGTJKF2b0NWRkeTo/GpEiPZHgv8sQSRdqdksCJb3Q' .
32 'xCuNIauvlr51IH269i60fq7HkJ5tbGNgQXYRTLgAuI9qHc8aWHAAAAAASUVORK5CYII='
33);
34define
35(
36 'IMG_45x90_PHP_GD_NA', // 45x90, red on pink: "ERROR: PHP-GD is not available"
37 'iVBORw0KGgoAAAANSUhEUgAAAC0AAABaCAYAAAAsPd/jAAABmElEQVRo3u2aS47DIAxA24qD9P6n' .
38 '4iadFVKG8T+hTKuH1AUBk4dtAja9v3p/3T6sPG4fWIAGGmiggQYaaKCB/kbo9qv2fP7t0bvcNp57' .
39 'bWdlXWhPaH7Zsa61DahjPSq71T00QK9Ilhc1HTWl5QIZMEtWGafmHhnfz1giKPsom1t7gdR2rFtg' .
40 '1rgm9Fgo43cWfF6AEWuOfsr4d1IIQAMNNNBAAw000ED/t2jcC7Ok8CoSqUdiPys6F8ZrKdBo8GrJ' .
41 'SoGAF51P7XvcY55QNG0hajoabWci6qtlTPfwZhz1YwusGMG3t7tCdr0IE2pb/HmO9JNWJBoH+hLo' .
42 'So5uO3Q2E7pQGV9wfeFpREo6Vq8qpERj0Jq177Q3uHQYmjcU7fkS6Fnbq3z9cp/ufQtsXdPVT59l' .
43 'oaRPs40D/VZo55LHXRul260Vh37cIxLYajtZtL8VJ3qblNJ+Lu8R7a/1s+SNeuz/Htb5YeWG5P4L' .
44 'IQsU7V+dqLGoW0gj2mnsrKa9nIhyzGUbBxpooIEGGmiggQYaaKCBBhpooAPlB5v19Mx7m4CJAAAA' .
45 'AElFTkSuQmCC'
46);
47define
48(
49 'IMG_45x90_RACK_NOT_FOUND', // 45x90, red on pink: "ERROR: rack doesn't exist"
50 'iVBORw0KGgoAAAANSUhEUgAAAC0AAABaCAYAAAAsPd/jAAABgElEQVRo3u2ZWxLCIAxFtcNC3P+q' .
51 'upP6xQyDSQgkWq2HGT8oj56GwCXxfuz7cfuxst1+sAANNNBAAw000EADfUXo8vLk8Xjtte9yW30+' .
52 'aouOHUKPBvUva+taW4Vq696xp7qHBjgqwsoXV0dtKS0XmAGzxgrzrLvHjO/PrIRj7BZabu0FUltb' .
53 't8CseU3oulHqLwreb0DPatZ+wvx3UghAAw000EADDTTQQCeVlSABS39F3iMSiGrB6SgYngyCS+iT' .
54 '+5dJuQsLagE4Dh3ZYIvAuT5dIeovEs2fbukerk/ELFicaBzoFOig9F7X0s583wVlXPvaGbmWct3e' .
55 'vzqUZGVxK1Y7kUeu27p0Dkt92/7G+X2uuHz8lue5QI1cJR1auxtoltN8NQKq+DQyDvSp0G+Q//dD' .
56 'W0fc4gf9UTSuybWllKMrwYTolCVgTYJHEXhC+iDH0pKYaMBJcl5SN5fX0sETpSwBa3Jt3dISfRoZ' .
57 'BxpooIEGGmiggQYaaKCBBhpooB3lCc5C4kpZ4AwVAAAAAElFTkSuQmCC'
58);
59define
60(
61 'IMG_45x90_MALF_REQ', // 45x90, red on pink: "ERROR: malformed request"
62 'iVBORw0KGgoAAAANSUhEUgAAAC0AAABaCAYAAAAsPd/jAAABdUlEQVRo3u2aSw6FIAxF9YWFuP9V' .
63 'sRPfiMQoLS0gojkkDvifQPHS6rrHuC8vS7/lhQlooIEGGmiggQYa6C9Ch0vJtl1bxZivS+Wluta+' .
64 'RehSp/Nkx7xUl6COeWvfR81DAiylzM4HU0NpKzUT8IBpfTPj1JuHx/Y9O2Ho+2vabmmCXN0xr4Fp' .
65 '46rQ6aCkpxX8fAAtu5naZcZfCSEADTTQQAMNNNBAA13piViuuU3e+AgfkbhHybmVnE+Ls5sLKUi+' .
66 'YVXcwxKLOOZLsZAzsGWc22260wGzhiJClwm0ENcNh3b8Smtnw5jwxoGeHtp5eFnp52Xcs501Et/w' .
67 'Pq9/T1sk3lM+1dW0t8QPge54jx4DnQu6x2iK9iPjQAM9+X3kQzLu8ZYlSS993JfGznGc3vWhu0x7' .
68 '/UnJE1f+RAg9bKzZVp1+ox26lxxL4zg+6AfzRB459pRrki7YdF8ZL/wRg7jMfA1lpYEGGmiggQYa' .
69 'aKCBBhpooIHW0h8839XO8L3K4AAAAABJRU5ErkJggg=='
70);
71define
72(
73 'IMG_1x1_BLACK', // 1x1, single black pixel
74 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAAXNSR0IArs4c6QAAAAxJREFUCNdj' .
75 'YGBgAAAABAABJzQnCgAAAABJRU5ErkJggg=='
76);
77define
78(
79 'IMG_76x17_ERROR', // 76x17, red on white: "ERROR"
80 'iVBORw0KGgoAAAANSUhEUgAAAEwAAAARCAYAAAB3h0oCAAAAAXNSR0IArs4c6QAAALBJREFUWMPt' .
81 'WFsOwCAIG4v3vzL7WEyWxQdVwM1A4l/F2iHVETPzESGOMyTAInURRP0suUhb2FIho/jWXO38w4KN' .
82 'LPDGEt2jlgPBZxFKc2o8UT7Lj6SkAmfw1nx+28MkVWQlcjT9EOwjLqnpaNImi+I1j/YSl5RY/gx+' .
83 'VCCF/MnkCz4JZQtvEUXx1nyW9jCUlPVLbTJ/3MO2dsnWRq2Nwl2wTarM51rhsVEnDhT/w7C4APaJ' .
84 'ZhkIGYaUAAAAAElFTkSuQmCC'
85);
86
3a089a44
DO
87// The default approach is to treat an error as fatal, in which case
88// some message is output and the user is left there. Inheriting classes
89// represent more specific cases, some of which can be handled in a
90// "softer" way (see below).
91class RackTablesError extends Exception
92{
9dba1777 93 const INTERNAL = 0; // the default code
3a089a44
DO
94 const DB_WRITE_FAILED = 3;
95 const NOT_AUTHENTICATED = 4;
3a089a44
DO
96 const MISCONFIGURED = 6;
97 protected final function genHTMLPage ($title, $text)
b135a49d 98 {
9bbaeb79
AA
99 global $helpdesk_banner, $debug_mode;
100 if (isset ($debug_mode) && $debug_mode && $this->code != RackTablesError::NOT_AUTHENTICATED)
101 {
102 // in debug mode, dump backtrace instead of standard page
103 // NOT_AUTHENTICATED exception does not need debugging, so it is skipped
104 printGenericException ($this);
105 return;
106 }
107
3a089a44
DO
108 header ('Content-Type: text/html; charset=UTF-8');
109 echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'."\n";
110 echo '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'."\n";
111 echo "<head><title>${title}</title>";
56a0bd8c
DO
112 echo "</head><body>${text}";
113 if (isset ($helpdesk_banner))
114 echo '<hr>' . $helpdesk_banner;
115 echo '</body></html>';
b135a49d 116 }
2d0ccf4f
AA
117 protected static function formatString ($string)
118 {
b5b969c9 119 return isCLIMode() ? $string : stringForLabel ($string, 80);
2d0ccf4f 120 }
3a089a44 121 public function dispatch()
b135a49d 122 {
3a089a44
DO
123 $msgheader = array
124 (
3a089a44
DO
125 self::MISCONFIGURED => 'Configuration error',
126 self::INTERNAL => 'Internal error',
127 self::DB_WRITE_FAILED => 'Database write failed',
3a089a44
DO
128 );
129 $msgbody = array
130 (
3a089a44
DO
131 self::MISCONFIGURED => '<h2>Configuration error</h2><br>' . $this->message,
132 self::INTERNAL => '<h2>Internal error</h2><br>' . $this->message,
133 self::DB_WRITE_FAILED => '<h2>Database write failed</h2><br>' . $this->message,
3a089a44
DO
134 );
135 switch ($this->code)
136 {
137 case self::NOT_AUTHENTICATED:
138 header ('WWW-Authenticate: Basic realm="' . getConfigVar ('enterprise') . ' RackTables access"');
4dd00f87 139 header ('HTTP/1.1 401 Unauthorized');
9bbaeb79
AA
140 $this->genHTMLPage ('Not authenticated', '<h2>This system requires authentication. You should use a username and a password.</h2>');
141 break;
3a089a44
DO
142 case self::MISCONFIGURED:
143 case self::INTERNAL:
144 case self::DB_WRITE_FAILED:
3a089a44
DO
145 $this->genHTMLPage ($msgheader[$this->code], $msgbody[$this->code]);
146 break;
147 default:
148 throw new RackTablesError ('Dispatching error, unknown code ' . $this->code, RackTablesError::INTERNAL);
149 }
b135a49d
DY
150 }
151}
e0c09e31 152
3a089a44
DO
153class EntityNotFoundException extends RackTablesError
154{
4dd00f87 155 function __construct ($realm, $id)
c5f84f48 156 {
4dd00f87 157 parent::__construct ("Record '${realm}'#'${id}' does not exist");
c5f84f48 158 }
3a089a44 159 public function dispatch()
c5f84f48 160 {
e7f9f532 161 global $debug_mode;
e8d843f4 162 if (isset ($debug_mode) && $debug_mode)
e7f9f532
AA
163 {
164 printGenericException ($this);
165 return;
166 }
e35e9db5 167 showError ($this->message);
4dd00f87 168 redirectUser (buildRedirectURL ('index', 'default'));
c5f84f48
DY
169 }
170}
171
40ee43a1
AA
172class ERetryNeeded extends RackTablesError
173{
4dd00f87 174 function __construct ($message)
40ee43a1
AA
175 {
176 $this->code = parent::INTERNAL;
177 parent::__construct ($message);
178 }
179}
180
3a089a44 181class InvalidArgException extends RackTablesError
94fe6370 182{
4c985eb5 183 // derive an instance of InvalidRequestArgException
2d3c0445 184 function newIRAE ($argname = NULL)
4c985eb5 185 {
2d3c0445
DO
186 if ($argname === NULL)
187 return new InvalidRequestArgException ($this->name, $this->value, $this->reason);
4c985eb5
DO
188 return new InvalidRequestArgException ($argname, $_REQUEST[$argname], $this->reason);
189 }
4dd00f87 190 function __construct ($name, $value, $reason = NULL)
0cc24e9a 191 {
2d0ccf4f
AA
192 $message = 'Argument \'' . self::formatString ($name) . '\'' .
193 ' of value ' . self::formatString (var_export ($value, TRUE), 200) .
194 ' is invalid' . (is_null ($reason) ? '' : ' (' . self::formatString ($reason, 100) . ')') .
65542bd8 195 '.';
3a089a44 196 parent::__construct ($message, parent::INTERNAL);
b027eea9
DO
197 $this->name = $name;
198 $this->value = $value;
199 $this->reason = $reason;
200 }
0cc24e9a
DY
201}
202
3a089a44
DO
203// this simplifies construction and helps in catching "soft"
204// errors (invalid input from the user)
4318ced5 205class InvalidRequestArgException extends InvalidArgException
0cc24e9a 206{
3a089a44 207 public function dispatch()
94fe6370 208 {
3a089a44 209 RackTablesError::genHTMLPage ('Assertion failed', '<h2>Assertion failed</h2><br>' . $this->message);
94fe6370 210 }
3a089a44
DO
211}
212
213// this wraps certain known PDO errors and is caught in process.php
214// as a "soft" error
ec523868 215class RTDatabaseError extends RackTablesError
3a089a44
DO
216{
217 public function dispatch()
218 {
ec523868 219 RackTablesError::genHTMLPage ('Database soft error', '<h2>Database soft error</h2><br>' . $this->message);
3a089a44
DO
220 }
221}
222
223// gateway failure is a common case of a "soft" error, some functions do catch this
224class RTGatewayError extends RackTablesError
225{
226 public function dispatch()
94fe6370 227 {
3a089a44 228 RackTablesError::genHTMLPage ('Gateway error', '<h2>Gateway error</h2><br>' . $this->message);
94fe6370
DO
229 }
230}
231
3ec33017
DO
232# "Permission denied" is a very common case, which in some situations is
233# treated as a "soft" error.
234class RTPermissionDenied extends RackTablesError
235{
236 public function dispatch()
237 {
221327e3
DO
238 global $pageno, $tabno,
239 $user_given_tags,
240 $target_given_tags,
241 $auto_tags,
242 $expl_tags,
243 $impl_tags;
4dd00f87
DO
244 header ('Content-Type: text/html; charset=UTF-8');
245 echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' . "\n";
246 echo '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">' . "\n";
247 echo "<head><title>RackTables: access denied</title>\n";
248 printPageHeaders();
249 echo '</head><body>';
221327e3
DO
250 echo "<table border=1 cellspacing=0 cellpadding=3 width='50%' align=center>\n";
251 echo '<tr><th colspan=2><h3>' . getImageHREF ('DENIED') . ' access denied ';
252 echo getImageHREF ('DENIED') . '</h3></th></tr>';
4dd00f87 253 echo '<tr><th width="50%" class=tagchain>User given tags:</th><td class=tagchain>';
221327e3 254 echo serializeTags ($user_given_tags) . "&nbsp;</td></tr>\n";
4dd00f87 255 echo '<tr><th width="50%" class=tagchain>Target given tags:</th><td class=tagchain>';
221327e3 256 echo serializeTags ($target_given_tags) . "&nbsp;</td></tr>\n";
4dd00f87 257 echo '<tr><th width="50%" class=tagchain>Effective explicit tags:</th><td class=tagchain>';
221327e3 258 echo serializeTags ($expl_tags) . "&nbsp;</td></tr>\n";
4dd00f87 259 echo '<tr><th width="50%" class=tagchain>Effective implicit tags:</th><td class=tagchain>';
221327e3 260 echo serializeTags ($impl_tags) . "&nbsp;</td></tr>\n";
4dd00f87 261 echo '<tr><th width="50%" class=tagchain>Automatic tags:</th><td class=tagchain>';
221327e3
DO
262 echo serializeTags ($auto_tags) . "&nbsp;</td></tr>\n";
263 echo "<tr><th width='50%' class=tdright>Requested page:</th><td class=tdleft>${pageno}</td></tr>\n";
264 echo "<tr><th width='50%' class=tdright>Requested tab:</th><td class=tdleft>${tabno}</td></tr>\n";
265 echo "<tr><td colspan=2 align=center>Click <a href='index.php?logout'>here</a> to logout.</td></tr>\n";
266 echo "</table>\n";
4dd00f87 267 echo '</body></html>';
3ec33017
DO
268 }
269}
270
36cad4bd
DO
271class RackCodeError extends RackTablesError
272{
273 protected $lineno;
274 function __construct ($message, $lineno = 'unknown')
275 {
276 # RackCodeError without a catch-block is very likely an internal error
330792e5 277 parent::__construct ($message, self::INTERNAL);
36cad4bd
DO
278 $this->lineno = $lineno;
279 }
280 public function dispatch()
281 {
330792e5 282 parent::genHTMLPage ('RackCode error', '<h2>RackCode error on line ' . $this->lineno . '</h2><br>' . $this->message);
36cad4bd
DO
283 }
284}
285
8d3ab47c
DO
286// Whether there is a failure to produce a normal image, this class will emit one
287// of the hardcoded last-resort images without the dependency on PHP-GD.
288class RTImageError extends RackTablesError
289{
290 protected $imgbin;
d75d212e 291 function __construct ($subject = NULL)
8d3ab47c
DO
292 {
293 $map = array
294 (
295 'pbar_error' => IMG_100x10_PBAR_ERROR,
296 'pbar_php_gd_error' => IMG_100x10_PHP_GD_NA,
297 'pbar_arg_error' => IMG_100x10_ARG_ERROR,
298 'rack_php_gd_error' => IMG_45x90_PHP_GD_NA,
299 'rack_not_found' => IMG_45x90_RACK_NOT_FOUND,
300 'rack_arg_error' => IMG_45x90_MALF_REQ,
301 'access_denied' => IMG_1x1_BLACK,
302 );
303 $this->imgbin = base64_decode (array_fetch ($map, $subject, IMG_76x17_ERROR));
304 }
305 public function dispatch()
306 {
ff9b6ad3 307 header ('Content-Type: image/png');
8d3ab47c
DO
308 echo $this->imgbin;
309 }
310}
311
4dd00f87 312function dumpArray ($arr)
f77323f1
DO
313{
314 echo '<table class="exceptionParametersDump">';
4dd00f87 315 foreach ($arr as $key => $value)
a0bdf6dc 316 echo '<tr><th>' . stringForTD ($key) . '</th><td>' . stringForTD ($value, 100) . '</td></tr>';
f77323f1
DO
317 echo '</table>';
318}
319
4dd00f87 320function stringTrace ($trace)
e7aa0333
DY
321{
322 $ret = '';
a20a4e3c
DO
323 foreach ($trace as $line)
324 {
c06d6308 325 if (isset ($line['file']) && isset ($line['line']))
4dd00f87
DO
326 $ret .= $line['file'] . ':' . $line['line'] . ' ';
327 $ret .= $line['function'] . '(';
328 $f = TRUE;
55eefced 329 if (isset ($line['args']) && is_array ($line['args']))
a20a4e3c
DO
330 foreach ($line['args'] as $arg)
331 {
4dd00f87
DO
332 if (! $f)
333 $ret .= ', ';
a20a4e3c 334 if (is_string ($arg))
4dd00f87 335 $printarg = '\'' . $arg . '\'';
a20a4e3c
DO
336 elseif (is_null ($arg))
337 $printarg = 'NULL';
338 elseif (is_array ($arg))
339 $printarg = print_r ($arg, 1);
5930d0f6 340 elseif (is_object ($arg))
4dd00f87 341 $printarg = 'Object(' . get_class ($arg) . ')';
a20a4e3c
DO
342 else
343 $printarg = $arg;
344 $ret .= $printarg;
4dd00f87 345 $f = FALSE;
a20a4e3c 346 }
e7aa0333
DY
347 $ret .= ")\n";
348 }
349 return $ret;
350}
351
4dd00f87 352function printPDOException ($e)
e7aa0333 353{
4dd00f87 354 header ('HTTP/1.1 500 Internal Server Error');
878512c6 355 header ('Content-Type: text/html; charset=UTF-8');
4dd00f87
DO
356 echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' . "\n";
357 echo '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">' . "\n";
e7aa0333 358 echo "<head><title> PDO Exception </title>\n";
6e5c6947
DO
359 echo "<link rel=stylesheet type='text/css' href='?module=chrome&uri=css/pi.css' />\n";
360 echo "<link rel=icon href='?module=chrome&uri=pix/favicon.ico' type='image/x-icon' />\n";
e7aa0333 361 echo '</head> <body>';
4dd00f87
DO
362 echo '<h2>Pdo exception: ' . get_class ($e) . '</h2><code>' . $e->getMessage() . '</code> (<code>' . $e->getCode() . '</code>)';
363 echo '<p>at file <code>' . $e->getFile() . '</code>, line <code>' . $e->getLine() . '</code></p><pre>';
364 echo stringTrace ($e->getTrace());
e7aa0333
DY
365 echo '</pre>';
366 echo '<h2>Error info:</h2>';
367 echo '<pre>';
4dd00f87 368 print_r ($e->errorInfo);
e7aa0333
DY
369 echo '</pre>';
370 echo '<h2>Parameters:</h2>';
371 echo '<h3>GET</h3>';
4dd00f87 372 dumpArray ($_GET);
e7aa0333 373 echo '<h3>POST</h3>';
4dd00f87 374 dumpArray ($_POST);
e7aa0333 375 echo '<h3>COOKIE</h3>';
4dd00f87 376 dumpArray ($_COOKIE);
e7aa0333 377 echo '</body></html>';
e7aa0333
DY
378}
379
4dd00f87 380function printGenericException ($e)
f77323f1 381{
4dd00f87 382 header('HTTP/1.1 500 Internal Server Error');
878512c6 383 header ('Content-Type: text/html; charset=UTF-8');
4dd00f87
DO
384 echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' . "\n";
385 echo '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">' . "\n";
f77323f1 386 echo "<head><title> Exception </title>\n";
6e5c6947
DO
387 echo "<link rel=stylesheet type='text/css' href='?module=chrome&uri=css/pi.css' />\n";
388 echo "<link rel=icon href='?module=chrome&uri=pix/favicon.ico' type='image/x-icon' />\n";
f77323f1 389 echo '</head> <body>';
4dd00f87
DO
390 echo '<h2>Uncaught exception: ' . get_class ($e) . '</h2><code>' . $e->getMessage() . '</code> (<code>' . $e->getCode() . '</code>)';
391 echo '<p>at file <code>' . $e->getFile() . '</code>, line <code>' . $e->getLine() . '</code></p><pre>';
392 echo stringTrace ($e->getTrace());
f77323f1
DO
393 echo '</pre>';
394 echo '<h2>Parameters:</h2>';
395 echo '<h3>GET</h3>';
4dd00f87 396 dumpArray ($_GET);
f77323f1 397 echo '<h3>POST</h3>';
4dd00f87 398 dumpArray ($_POST);
f77323f1 399 echo '<h3>COOKIE</h3>';
4dd00f87 400 dumpArray ($_COOKIE);
f77323f1 401 echo '</body></html>';
f77323f1
DO
402}
403
4dd00f87 404function printException ($e)
f77323f1 405{
3a089a44 406 if ($e instanceof RackTablesError)
9bbaeb79 407 $e->dispatch();
ca5a7f8b 408 elseif ($e instanceof PDOException)
4dd00f87 409 printPDOException ($e);
f77323f1 410 else
4dd00f87 411 printGenericException ($e);
f77323f1
DO
412}
413
e0c09e31 414?>