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
|
|
|
header($_SERVER['SERVER_PROTOCOL'] . $httpHeader, true); |
90
|
|
|
header('X-Error-Message: ' . $message); |
91
|
|
|
header('X-Error-File: ' . $file); |
92
|
|
|
header('X-Error-Line: ' . $line); |
93
|
|
|
if (canShowError()) { |
94
|
|
|
$file_lines = file_exists($file) ? file($file) : array(); |
95
|
|
|
$range = ($line - 15) < 0 ? range(1, 30) : range($line - 15, $line + 15); |
96
|
|
|
$lines = array(); |
97
|
|
|
|
98
|
|
|
foreach ($range as $line_number) { |
99
|
|
|
if(isset($file_lines[$line_number-1])) { |
100
|
|
|
$lines[$line_number] = $file_lines[$line_number-1]; |
101
|
|
|
} |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
$error = array( |
105
|
|
|
'message' => $message, |
106
|
|
|
'file' => $file, |
107
|
|
|
'line' => $line, |
108
|
|
|
'code' => $code, |
109
|
|
|
'lines' => $lines, |
110
|
|
|
'trace' => $trace, |
111
|
|
|
'httpHeader' => $httpHeader, |
112
|
|
|
); |
113
|
|
View Code Duplication |
if (file_exists(realpath(__DIR__) . '/errorviewdetailed.php')) { |
|
|
|
|
114
|
|
|
include(realpath(__DIR__) . '/errorviewdetailed.php'); |
115
|
|
|
} else { |
116
|
|
|
header('Content-type: application/json'); |
117
|
|
|
die(json_encode($error)); |
118
|
|
|
} |
119
|
|
|
exit; |
120
|
|
View Code Duplication |
} else { |
|
|
|
|
121
|
|
|
if (file_exists(realpath(__DIR__) . '/errorviewcompact.php')) { |
122
|
|
|
include(realpath(__DIR__) . '/errorviewcompact.php'); |
123
|
|
|
} else { |
124
|
|
|
header('Content-type: application/json'); |
125
|
|
|
die(json_encode('An error occured.')); |
126
|
|
|
} |
127
|
|
|
} |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
function canShowError() |
131
|
|
|
{ |
132
|
|
|
if (file_exists('../config.json') && !isset($_SESSION['cloudcontrol'])) { |
133
|
|
|
$config = file_get_contents('../config.json'); |
134
|
|
|
$config = json_decode($config); |
135
|
|
|
if (isset($config->showErrorsToAll)) { |
136
|
|
|
return $config->showErrorsToAll; |
137
|
|
|
} |
138
|
|
|
} else { |
139
|
|
|
return true; |
140
|
|
|
} |
141
|
|
|
} |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.