/
error_handler.php
211 lines (206 loc) · 7.4 KB
/
error_handler.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
<?php
/**
* Error handler
*
* Provides Error Capturing for Framework errors.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs
* @since CakePHP(tm) v 0.10.5.1732
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
*
* Error Handler provides basic error and exception handling for your application. It captures and
* handles all unhandled exceptions and errors. Displays helpful framework errors when debug > 1.
*
* ### Uncaught exceptions
*
* When debug < 1 a CakeException will render 404 or 500 errors. If an uncaught exception is thrown
* and it is a type that ErrorHandler does not know about it will be treated as a 500 error.
*
* ### Implementing application specific exception handling
*
* You can implement application specific exception handling in one of a few ways. Each approach
* gives you different amounts of control over the exception handling process.
*
* - Set Configure::write('Exception.handler', 'YourClass::yourMethod');
* - Create AppController::appError();
* - Set Configure::write('Exception.renderer', 'YourClass');
*
* #### Create your own Exception handler with `Exception.handler`
*
* This gives you full control over the exception handling process. The class you choose should be
* loaded in your app/config/bootstrap.php, so its available to handle any exceptions. You can
* define the handler as any callback type. You can't combine this with other Exception settings.
*
* #### Using `AppController::appError();`
*
* This controller method is called instead of the default exception rendering. It receives the
* thrown exception as its only argument. You should implement your error handling in that method.
*
* #### Using a custom renderer with `Exception.renderer`
*
* If you don't want to take control of the exception handling, but want to change how exceptions are
* rendered you can use `Exception.renderer` to choose a class to render exception pages. By default
* `ExceptionRenderer` is used. Your custom exception renderer class should be placed in app/libs.
*
* Your custom renderer should expect an exception in its constructor, and implement a render method.
* Failing to do so will cause additional errors.
*
* #### Logging exceptions
*
* Using the built-in exception handling, you can log all the exceptions
* that are dealt with by ErrorHandler by setting `Exception.log` to true in your core.php.
* Enabling this will log every exception to CakeLog and the configured loggers.
*
* ### PHP errors
*
* Error handler also provides the built in features for handling php errors (trigger_error).
* While in debug mode, errors will be output to the screen using debugger. While in production mode,
* errors will be logged to CakeLog. You can control which errors are logged by setting
* `Error.level` in your core.php.
*
* #### Logging errors
*
* When ErrorHandler is used for handling errors, you can enable error logging by setting `Error.log` to true.
* This will log all errors to the configured log handlers.
*
* #### Controlling what errors are logged/displayed
*
* You can control which errors are logged / displayed by ErrorHandler by setting `Error.level`. Setting this
* to one or a combination of a few of the E_* constants will only enable the specified errors.
*
* e.g. `Configure::write('Error.level', E_ALL & ~E_NOTICE);`
*
* Would enable handling for all non Notice errors.
*
* @package cake
* @subpackage cake.cake.libs
* @see ExceptionRenderer for more information on how to customize exception rendering.
*/
class ErrorHandler {
/**
* Set as the default exception handler by the CakePHP bootstrap process.
*
* This will either use an AppError class if your application has one,
* or use the default ExceptionRenderer.
*
* @return void
* @see http://php.net/manual/en/function.set-exception-handler.php
*/
public static function handleException(Exception $exception) {
App::import('Core', 'ExceptionRenderer');
$config = Configure::read('Exception');
if (!empty($config['log'])) {
if (!class_exists('CakeLog')) {
require LIBS . 'cake_log.php';
}
CakeLog::write(LOG_ERR, '[' . get_class($exception) . '] ' . $exception->getMessage());
}
if ($config['renderer'] !== 'ExceptionRenderer') {
App::import('Lib', $config['renderer']);
}
$error = new $config['renderer']($exception);
$error->render();
}
/**
* Set as the default error handler by CakePHP. Use Configure::write('Error.handler', $callback), to use your own
* error handling methods. This function will use Debugger to display errors when debug > 0. And
* will log errors to CakeLog, when debug == 0.
*
* You can use Configure::write('Error.level', $value); to set what type of errors will be handled here.
* Stack traces for errors can be enabled with Configure::write('Error.trace', true);
*
* @param integer $code Code of error
* @param string $description Error description
* @param string $file File on which error occurred
* @param integer $line Line that triggered the error
* @param array $context Context
* @return boolean true if error was handled
*/
public static function handleError($code, $description, $file = null, $line = null, $context = null) {
$errorConfig = Configure::read('Error');
list($error, $log) = self::_mapErrorCode($code);
$debug = Configure::read('debug');
if ($debug) {
if (!class_exists('Debugger')) {
require LIBS . 'debugger.php';
}
$data = array(
'level' => $log,
'code' => $code,
'error' => $error,
'description' => $description,
'file' => $file,
'line' => $line,
'context' => $context,
'start' => 2,
'path' => Debugger::trimPath($file)
);
return Debugger::getInstance()->outputError($data);
} else {
if (!class_exists('CakeLog')) {
require LIBS . 'cake_log.php';
}
$message = $error . ' (' . $code . '): ' . $description . ' in [' . $file . ', line ' . $line . ']';
if (!empty($errorConfig['trace'])) {
if (!class_exists('Debugger')) {
require LIBS . 'debugger.php';
}
$trace = Debugger::trace(array('start' => 1, 'format' => 'log'));
$message .= "\nTrace:\n" . $trace . "\n";
}
return CakeLog::write($log, $message);
}
}
/**
* Map an error code into an Error word, and log location.
*
* @param int $code Error code to map
* @return array Array of error word, and log location.
*/
protected static function _mapErrorCode($code) {
switch ($code) {
case E_PARSE:
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
$error = 'Fatal Error';
$log = LOG_ERROR;
break;
case E_WARNING:
case E_USER_WARNING:
case E_COMPILE_WARNING:
case E_RECOVERABLE_ERROR:
$error = 'Warning';
$log = LOG_WARNING;
break;
case E_NOTICE:
case E_USER_NOTICE:
$error = 'Notice';
$log = LOG_NOTICE;
break;
case E_STRICT:
$error = 'Strict';
$log = LOG_NOTICE;
break;
case E_DEPRECATED:
$error = 'Deprecated';
$log = LOG_NOTICE;
break;
}
return array($error, $log);
}
}