1
|
|
|
<?php |
2
|
|
|
set_exception_handler('exceptionHandler'); |
3
|
|
|
set_error_handler('errorHandler'); |
4
|
|
|
register_shutdown_function('shutdownHandler'); |
5
|
|
|
|
6
|
|
|
/** |
7
|
|
|
* An uncaught exception will result in the rendering |
8
|
|
|
* of the exception as though it were an error |
9
|
|
|
* |
10
|
|
|
* @param $e |
11
|
|
|
*/ |
12
|
|
|
function exceptionHandler ($e) { |
13
|
|
|
renderError($e->getMessage(),$e->getFile(),$e->getLine(),$e->getCode(),$e->getTrace()); |
14
|
|
|
} |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* When an error occures, render it properly. |
18
|
|
|
* |
19
|
|
|
* @param $errno |
20
|
|
|
* @param $errstr |
21
|
|
|
* @param $errfile |
22
|
|
|
* @param $errline |
23
|
|
|
*/ |
24
|
|
|
function errorHandler ($errno, $errstr, $errfile, $errline) { |
25
|
|
|
renderError($errstr,$errfile,$errline,$errno,debug_backtrace()); |
26
|
|
|
} |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* When an error occurs that kills the process, still try |
30
|
|
|
* to show it using a shutdownHandler. |
31
|
|
|
*/ |
32
|
|
|
function shutdownHandler () { |
33
|
|
|
$error = error_get_last(); |
34
|
|
|
if (isset($error['type'], $error['message'], $error['file'], $error['line'])) { |
35
|
|
|
errorHandler($error['type'],$error['message'],$error['file'],$error['line']); |
36
|
|
|
}elseif ($error['type'] == 1) { |
37
|
|
|
dump($error); |
38
|
|
|
} |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Error handler specificly for json errors |
43
|
|
|
* |
44
|
|
|
* @param $file |
45
|
|
|
* @param $line |
46
|
|
|
*/ |
47
|
|
|
function handleJsonError($file, $line) |
48
|
|
|
{ |
49
|
|
|
$jsonErrorNr = json_last_error(); |
50
|
|
|
$errstr = ''; |
51
|
|
|
switch ($jsonErrorNr) { |
52
|
|
|
case JSON_ERROR_NONE: |
53
|
|
|
$errstr .= ' - No errors' . PHP_EOL; |
54
|
|
|
break; |
55
|
|
|
case JSON_ERROR_DEPTH: |
56
|
|
|
$errstr .= ' - Maximum stack depth exceeded' . PHP_EOL; |
57
|
|
|
break; |
58
|
|
|
case JSON_ERROR_STATE_MISMATCH: |
59
|
|
|
$errstr .= ' - Underflow or the modes mismatch' . PHP_EOL; |
60
|
|
|
break; |
61
|
|
|
case JSON_ERROR_CTRL_CHAR: |
62
|
|
|
$errstr .= ' - Unexpected control character found' . PHP_EOL; |
63
|
|
|
break; |
64
|
|
|
case JSON_ERROR_SYNTAX: |
65
|
|
|
$errstr .= ' - Syntax error, malformed JSON' . PHP_EOL; |
66
|
|
|
break; |
67
|
|
|
case JSON_ERROR_UTF8: |
68
|
|
|
$errstr .= ' - Malformed UTF-8 characters, possibly incorrectly encoded' . PHP_EOL; |
69
|
|
|
break; |
70
|
|
|
default: |
71
|
|
|
$errstr = ' - Unknown error' . PHP_EOL; |
72
|
|
|
break; |
73
|
|
|
} |
74
|
|
|
errorHandler ($jsonErrorNr, $errstr, $file, $line); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Displays the error in a human readable fashion for developers. |
79
|
|
|
* |
80
|
|
|
* @param string $message |
81
|
|
|
* @param string $file |
82
|
|
|
* @param string $line |
83
|
|
|
* @param int $code |
84
|
|
|
* @param array $trace |
85
|
|
|
* @param string $httpHeader |
86
|
|
|
*/ |
87
|
|
|
function renderError ($message='', $file='', $line='', $code=0, $trace=array(), $httpHeader = 'HTTP/1.0 500 Internal Server Error') { |
88
|
|
|
if (ob_get_contents()) ob_end_clean(); |
89
|
|
|
|
90
|
|
|
if (canShowError()) { |
91
|
|
|
$file_lines = file_exists($file) ? file($file) : array(); |
92
|
|
|
$range = ($line - 15) < 0 ? range(1, 30) : range($line - 15, $line + 15); |
93
|
|
|
$lines = array(); |
94
|
|
|
|
95
|
|
|
foreach ($range as $line_number) { |
96
|
|
|
if(isset($file_lines[$line_number-1])) { |
97
|
|
|
$lines[$line_number] = $file_lines[$line_number-1]; |
98
|
|
|
} |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
$error = array( |
102
|
|
|
'message' => $message, |
103
|
|
|
'file' => $file, |
104
|
|
|
'line' => $line, |
105
|
|
|
'code' => $code, |
106
|
|
|
'lines' => $lines, |
107
|
|
|
'trace' => $trace, |
108
|
|
|
'httpHeader' => $httpHeader, |
109
|
|
|
); |
110
|
|
|
|
111
|
|
|
if (PHP_SAPI === 'cli') { |
112
|
|
|
renderCliException($message, $file, $line, $trace, $lines); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
if (file_exists(realpath(__DIR__) . '/errorviewdetailed.php')) { |
116
|
|
|
header($_SERVER['SERVER_PROTOCOL'] . $httpHeader, true); |
117
|
|
|
include(realpath(__DIR__) . '/errorviewdetailed.php'); |
118
|
|
|
} else { |
119
|
|
|
header($_SERVER['SERVER_PROTOCOL'] . $httpHeader, true); |
120
|
|
|
header('Content-type: application/json'); |
121
|
|
|
die(json_encode($error)); |
122
|
|
|
} |
123
|
|
|
exit; |
124
|
|
|
} else { |
125
|
|
|
header($_SERVER['SERVER_PROTOCOL'] . $httpHeader, true); |
126
|
|
|
header('X-Error-Message: ' . $message); |
127
|
|
|
header('X-Error-File: ' . $file); |
128
|
|
|
header('X-Error-Line: ' . $line); |
129
|
|
|
if (file_exists(realpath(__DIR__) . '/errorviewcompact.php')) { |
130
|
|
|
include(realpath(__DIR__) . '/errorviewcompact.php'); |
131
|
|
|
} else { |
132
|
|
|
header('Content-type: application/json'); |
133
|
|
|
die(json_encode('An error occured.')); |
134
|
|
|
} |
135
|
|
|
} |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
function canShowError() |
139
|
|
|
{ |
140
|
|
|
if (PHP_SAPI === 'cli') { |
141
|
|
|
return true; |
142
|
|
|
} |
143
|
|
|
if (file_exists('../config.json') && !isset($_SESSION['cloudcontrol'])) { |
144
|
|
|
$config = file_get_contents('../config.json'); |
145
|
|
|
$config = json_decode($config); |
146
|
|
|
if (isset($config->showErrorsToAll)) { |
147
|
|
|
return $config->showErrorsToAll; |
148
|
|
|
} |
149
|
|
|
} else { |
150
|
|
|
return true; |
151
|
|
|
} |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
function renderCliException($message, $file, $line, $trace, $lines) |
155
|
|
|
{ |
156
|
|
|
if (ob_get_contents()) ob_end_clean(); |
157
|
|
|
include(realpath(__DIR__) . '/errorviewcli.php'); |
158
|
|
|
exit; |
159
|
|
|
} |