Project

General

Profile

Bug #21168 » 12093_improved_errorhandling_v9.diff

Administrator Admin, 2009-10-12 14:34

View differences:

t3lib/config_default.php (Arbeitskopie)
)
),
'useCachingFramework' => 0, // Boolean: Enable this if you want to use the caching framework by default for the core caches cache_pages, cache_pagesection and cache_hash.
'displayErrors' => -1, // Integer, -1,0,1,2. 0=Do not display any PHP error messages. 1=Display error messages. 2=Display only if client matches TYPO3_CONF_VARS[SYS][devIPmask]. -1=Default setting. With this option, you can override the PHP setting "display_errors". It is suggested that you set this to "0" and enable the "error_log" option in php.ini instead.
'exceptionHandler' => 't3lib_error_ProductionExceptionHandler', // String: Classname to handle exceptions that might happen in the TYPO3-code. Leave empty to disable exception handling, or set to t3lib_error_ProductionExceptionHandler for nice error messages when something wents wrong, or to t3lib_error_DebugExceptionHandler for a complete stack trace of any encountered exception. Note that if devIPmask matches, t3lib_error_DebugExceptionHandler will be used, regardless of this setting.
'errorHandler' => '', // String: Classname to handle PHP errors. E.g.: t3lib_error_ErrorHandler.This class will turn the error into an exception (to be handled by the exceptionHandler).
'exceptionalErrors' => E_ALL ^ E_NOTICE, // Integer: The E_* constant that will be handled as an exception by t3lib_error_ErrorHandler. Default is "E_ALL ^ E_NOTICE" (6135) and "0" if displayError=0. Some values for errors: E_ALL=6143, E_ALL ^ E_NOTICE ^ E_WARNING=6133. See php documentation for more details on this integer.
'displayErrors' => -1, // Integer: -1,0,1,2. Configures whether PHP errors should be displayed. 0 = Do not display any PHP error messages. Overrides the value of “exceptionalErrors” and sets it to 0 (= no errors are turned into exceptions), the configured “productionExceptionHandler” is used as exception handler, 1 = Display error messages with the registered errorhandler. The configured “debugExceptionHandler” is used as exception handler. 2 = Display errors only if client matches TYPO3_CONF_VARS[SYS][devIPmask]. If devIPmask matches the users IP address the configured “debugExceptionHandler” is used for exceptions, if not “productionExceptionHandler” will be used. -1 = Default setting. With this option, you can override the PHP setting "display_errors". If devIPmask matches the users IP address the configured “debugExceptionHandler” is used for exceptions, if not “productionExceptionHandler” will be used.
'productionExceptionHandler' => 't3lib_error_ProductionExceptionHandler', // String: Classname to handle exceptions that might happen in the TYPO3-code. Leave empty to disable exception handling. Default: “t3lib_error_ProductionExceptionHandler”. This exception handler displays a nice error message when something went wrong. The error message is logged to the configured logs. Note: The configured "productionExceptionHandler" is used if displayErrors is set to “0” or to “-1” and devIPmask doesn't match the users IP.
'debugExceptionHandler' => 't3lib_error_DebugExceptionHandler', // String: Classname to handle exceptions that might happen in the TYPO3-code. Leave empty to disable exception handling. Default: “t3lib_error_DebugExceptionHandler”. This exception handler displays the complete stack trace of any encountered exception. The error message and the stack trace is logged to the configured logs. Note: The configured "debugExceptionHandler" is used if displayErrors is set to “1” and if displayErrors is “-1” or “2” and the devIPmask matches the users IP.
'errorHandler' => 't3lib_error_ErrorHandler', // String: Classname to handle PHP errors. E.g.: t3lib_error_ErrorHandler. This class displays and logs all errors that are registered as "errorHandlerErrors" ([SYS][errorHandlerErrors]). Leave empty to disable error handling. Errors can be logged to syslog (see: [SYS][systemLog]) to the installed developer log and to the "syslog" table. If an error is registered in "exceptionalErrors" ([SYS][exceptionalErrors]) it will be turned into an exception to be handled by the configured exceptionHandler.
'errorHandlerErrors'=> E_ALL ^ E_NOTICE, // Integer: The E_* constant that will be handled by the errorhandler. Default is "E_ALL ^ E_NOTICE".
'exceptionalErrors' => E_ALL ^ E_NOTICE ^ E_WARNING ^ E_USER_ERROR ^ E_USER_NOTICE ^ E_USER_WARNING, // Integer: The E_* constant that will be handled as an exception by t3lib_error_ErrorHandler. Default is "E_ALL ^ E_NOTICE ^ E_WARNING ^ E_USER_ERROR ^ E_USER_NOTICE ^ E_USER_WARNING" (4341) and "0" if displayError=0. Some values for errors: E_ALL=6143, E_ALL ^ E_NOTICE ^ E_WARNING=6133. See php documentation for more details on this integer.
'enable_errorDLOG' => 0, // Boolean: If set, errors are written to the developer log (requires an installed *devlog* extension).
'enable_exceptionDLOG' => 0, // Boolean: If set, exceptions are written to the developer log (requires an installed *devlog* extension).
),
'EXT' => Array ( // Options related to the Extension Management
'noEdit' => 1, // Boolean: If set, the Extension Manager does NOT allow extension files to be edited! (Otherwise both local and global extensions can be edited.)
......
$T3_SERVICES = array();
// Error & exception handling
$TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionHandler'] = $TYPO3_CONF_VARS['SYS']['exceptionHandler'];
$TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionHandler'] = $TYPO3_CONF_VARS['SYS']['productionExceptionHandler'];
$TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionalErrors'] = $TYPO3_CONF_VARS['SYS']['exceptionalErrors'];
// Turn error logging on/off.
if (($displayErrors=intval($TYPO3_CONF_VARS['SYS']['displayErrors']))!='-1') {
if ($displayErrors==2) { // Special value "2" enables this feature only if $TYPO3_CONF_VARS[SYS][devIPmask] matches
if (($displayErrors = intval($TYPO3_CONF_VARS['SYS']['displayErrors'])) != '-1') {
if ($displayErrors == 2) { // Special value "2" enables this feature only if $TYPO3_CONF_VARS[SYS][devIPmask] matches
if (t3lib_div::cmpIP(t3lib_div::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask'])) {
$displayErrors=1;
$TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionHandler'] = 't3lib_error_DebugExceptionHandler';
$displayErrors = 1;
} else {
$displayErrors=0;
$displayErrors = 0;
}
}
if ($displayErrors == 0) {
$TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionalErrors'] = 0;
}
if ($displayErrors == 1) {
$TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionHandler'] = $TYPO3_CONF_VARS['SYS']['debugExceptionHandler'];
define('TYPO3_ERRORHANDLER_MODE','debug');
}
@ini_set('display_errors', $displayErrors);
} elseif (t3lib_div::cmpIP(t3lib_div::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask'])) {
// with displayErrors = -1 (default), turn on debugging if devIPmask matches:
$TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionHandler'] = 't3lib_error_DebugExceptionHandler';
$TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionHandler'] = $TYPO3_CONF_VARS['SYS']['debugExceptionHandler'];
}
// Set PHP memory limit depending on value of $TYPO3_CONF_VARS["SYS"]["setMemoryLimit"]
if(intval($TYPO3_CONF_VARS["SYS"]["setMemoryLimit"])>16) {
@ini_set('memory_limit',intval($TYPO3_CONF_VARS["SYS"]["setMemoryLimit"]).'m');
......
// Define "TYPO3_DLOG" constant
define('TYPO3_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_DLOG']);
define('TYPO3_ERROR_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_errorDLOG']);
define('TYPO3_EXCEPTION_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_exceptionDLOG']);
// Unsetting other reserved global variables:
// Those which are/can be set in "stddb/tables.php" files:
unset($PAGES_TYPES);
t3lib/error/class.t3lib_error_abstractexceptionhandler.php (Arbeitskopie)
$this->echoExceptionWeb($exception);
}
}
/**
* Writes exception to different logs
*
* @param Exception $exception The exception
* @param string the context where the exception was thrown, WEB or CLI
* @return void
* @see t3lib_div::sysLog(), t3lib_div::devLog()
*/
protected function writeLogEntries(Exception $exception, $context) {
$filePathAndName = $exception->getFile();
$exceptionCodeNumber = ($exception->getCode() > 0) ? '#' . $exception->getCode() . ': ' : '';
$logTitle = 'Core: Exception handler (' . $context . ')';
$logMessage = 'Uncaught TYPO3 Exception: ' . $exceptionCodeNumber . $exception->getMessage() . ' | ' .
get_class($exception) . ' thrown in file ' . $filePathAndName . ' in line ' . $exception->getLine();
$backtrace = $exception->getTrace();
// write error message to the configured syslogs
t3lib_div::sysLog($logMessage, $logTitle, 4);
// In case an error occurs before a database connection exists, try
// to connect to the DB to be able to write the devlog/sys_log entry
if (is_object($GLOBALS['TYPO3_DB']) && empty($GLOBALS['TYPO3_DB']->link)) {
$GLOBALS['TYPO3_DB']->connectDB();
}
// write error message to devlog
// see: $TYPO3_CONF_VARS['SYS']['enable_exceptionDLOG']
if (TYPO3_EXCEPTION_DLOG) {
t3lib_div::devLog($logMessage, $logTitle, 3, array(
'TYPO3_MODE' => TYPO3_MODE,
'backtrace' => $backtrace
));
}
// write error message to sys_log table
$this->writeLog($logTitle . ': ' . $logMessage);
}
/**
* Writes an exception in the sys_log table
*
* @param string Default text that follows the message.
* @return void
*/
protected function writeLog($logMessage) {
if (is_object($GLOBALS['TYPO3_DB']) && !empty($GLOBALS['TYPO3_DB']->link)) {
$userId = 0;
$workspace = 0;
if (is_object($GLOBALS['BE_USER'])) {
if (isset($GLOBALS['BE_USER']->user['uid'])) {
$userId = $GLOBALS['BE_USER']->user['uid'];
}
if (isset($GLOBALS['BE_USER']->workspace)) {
$workspace = $GLOBALS['BE_USER']->workspace;
}
}
$fields_values = Array (
'userid' => $userId,
'type' => 5,
'action' => 0,
'error' => 2,
'details_nr' => 0,
'details' => $logMessage,
'IP' => t3lib_div::getIndpEnv('REMOTE_ADDR'),
'tstamp' => $GLOBALS['EXEC_TIME'],
'workspace' => $workspace
);
$GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_log', $fields_values);
}
}
}
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/error/class.t3lib_error_abstractexceptionhandler.php']) {
t3lib/error/class.t3lib_error_debugexceptionhandler.php (Arbeitskopie)
// $moreInformationLink = ($exceptionCodeNumber != '') ? '(<a href="http://typo3.org/go/exception/' . $exception->getCode() . '">More information</a>)' : '';
$backtraceCode = $this->getBacktraceCode($exception->getTrace());
$this->writeLogEntries($exception, 'WEB');
echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
......
*/
public function echoExceptionCLI(Exception $exception) {
$filePathAndName = $exception->getFile();
$exceptionCodeNumber = ($exception->getCode() > 0) ? '#' . $exception->getCode() . ': ' : '';
$this->writeLogEntries($exception, 'CLI');
echo "\nUncaught TYPO3 Exception " . $exceptionCodeNumber . $exception->getMessage() . "\n";
echo "thrown in file " . $filePathAndName . "\n";
t3lib/error/class.t3lib_error_productionexceptionhandler.php (Arbeitskopie)
if (!headers_sent()) {
header("HTTP/1.1 500 Internal Server Error");
}
$this->writeLogEntries($exception,'WEB');
t3lib_timeTrack::debug_typo3PrintError(get_class($exception), $exception->getMessage(), 0, t3lib_div::getIndpEnv('TYPO3_SITE_URL'));
}
......
* @return void
*/
public function echoExceptionCLI(Exception $exception) {
$this->writeLogEntries($exception,'CLI');
exit(1);
}
}
t3lib/error/interface.t3lib_error_errorhandlerinterface.php (Arbeitskopie)
interface t3lib_error_ErrorHandlerInterface {
/**
* Defines which error levels result should result in an exception thrown.
* Registers this class as default error handler
*
* @param integer $exceptionalErrors The integer representing the E_* error level to handle as exceptions
* @param integer The integer representing the E_* error level which should be
* handled by the registered error handler.
* @return void
*/
public function setErrorHandlerForExceptionalErrors($exceptionalErrors);
public function __construct($errorHandlerErrors);
/**
* Handles an error by converting it into an exception
* Defines which error levels should result in an exception thrown.
*
* @param integer $errorLevel The error level - one of the E_* constants
* @param string $errorMessage The error message
* @param string $errorFile Name of the file the error occurred in
* @param integer $errorLine Line number where the error occurred
* @param integer The integer representing the E_* error level to handle as exceptions
* @return void
* @throws t3lib_error_Exception with the data passed to this method
*/
public function setExceptionalErrors($exceptionalErrors);
/**
* Handles an error.
* If the error is registered as exceptionalError it will by converted into an exception, to be handled
* by the configured exceptionhandler. Additionall the error message is written to the configured logs.
* If TYPO3_MODE is 'BE' the error message is also added to the flashMessageQueue, in FE the error message
* is displayed in the admin panel (as TsLog message)
*
* @param integer The error level - one of the E_* constants
* @param string The error message
* @param string Name of the file the error occurred in
* @param integer Line number where the error occurred
* @return void
* @throws t3lib_error_Exception with the data passed to this method if the error is registered as exceptionalError
*/
public function handleError($errorLevel, $errorMessage, $errorFile, $errorLine);
}
t3lib/error/class.t3lib_error_errorhandler.php (Arbeitskopie)
*
* @package TYPO3
* @subpackage t3lib_error
* @author Rupert Germann <rupi@gmx.li>
* @version $Id: ErrorHandler.php 3195 2009-09-17 11:27:14Z k-fish $
*/
class t3lib_error_ErrorHandler implements t3lib_error_ErrorHandlerInterface {
/**
* @var array
* Error levels which should result in an exception thrown.
*
* @var integer
*/
protected $exceptionalErrors = array();
/**
* Defines which error levels result should result in an exception thrown.
* Registers this class as default error handler
*
* @param integer $exceptionalErrors The integer representing the E_* error level to handle as exceptions
* @param integer The integer representing the E_* error level which should be
* handled by the registered error handler.
* @return void
*/
public function setErrorHandlerForExceptionalErrors($exceptionalErrors) {
public function __construct($errorHandlerErrors) {
set_error_handler(array($this, 'handleError'), $errorHandlerErrors);
}
/**
* Defines which error levels should result in an exception thrown.
*
* @param integer The integer representing the E_* error level to handle as exceptions
* @return void
*/
public function setExceptionalErrors($exceptionalErrors) {
$this->exceptionalErrors = (int)$exceptionalErrors;
set_error_handler(array($this, 'handleError'), $this->exceptionalErrors);
}
/**
* Handles an error by converting it into an exception
* Handles an error.
* If the error is registered as exceptionalError it will by converted into an exception, to be handled
* by the configured exceptionhandler. Additionall the error message is written to the configured logs.
* If TYPO3_MODE is 'BE' the error message is also added to the flashMessageQueue, in FE the error message
* is displayed in the admin panel (as TsLog message)
*
* @param integer $errorLevel The error level - one of the E_* constants
* @param string $errorMessage The error message
* @param string $errorFile Name of the file the error occurred in
* @param integer $errorLine Line number where the error occurred
* @param integer The error level - one of the E_* constants
* @param string The error message
* @param string Name of the file the error occurred in
* @param integer Line number where the error occurred
* @return void
* @throws t3lib_error_Exception with the data passed to this method
* @throws t3lib_error_Exception with the data passed to this method if the error is registered as exceptionalError
*/
public function handleError($errorLevel, $errorMessage, $errorFile, $errorLine) {
// don't do anything if error_reporting is disabled by an @ sign
if (error_reporting()==0) { return TRUE; }
$errorLevels = array (
E_WARNING => 'Warning',
E_NOTICE => 'Notice',
......
E_RECOVERABLE_ERROR => 'Catchable Fatal Error'
);
$message = 'PHP ' .$errorLevels[$errorLevel] . ': ' . $errorMessage . ' in ' . $errorFile . ' line ' . $errorLine;
if ($errorLevel & $this->exceptionalErrors) {
throw new t3lib_error_Exception($errorLevels[$errorLevel] . ': ' . $errorMessage . ' in ' . $errorFile . ' line ' . $errorLine, 1);
throw new t3lib_error_Exception($message, 1);
} else {
switch ($errorLevel) {
case E_USER_ERROR:
case E_RECOVERABLE_ERROR:
$severity = 2;
break;
case E_USER_WARNING:
case E_WARNING:
$severity = 1;
break;
default:
$severity = 0;
break;
}
$logTitle = 'Core: Error handler (' . TYPO3_MODE . ')';
// Write error message to the configured syslogs,
// see: $TYPO3_CONF_VARS['SYS']['systemLog']
t3lib_div::sysLog($message, $logTitle, $severity);
// In case an error occurs before a database connection exists, try
// to connect to the DB to be able to write an entry to devlog/sys_log
if (is_object($GLOBALS['TYPO3_DB']) && empty($GLOBALS['TYPO3_DB']->link)) {
$GLOBALS['TYPO3_DB']->connectDB();
}
// Write error message to devlog extension(s),
// see: $TYPO3_CONF_VARS['SYS']['enable_errorDLOG']
if (TYPO3_ERROR_DLOG) {
t3lib_div::devLog($message, $logTitle, $severity + 1);
}
// Write error message to TSlog (admin panel)
if (is_object($GLOBALS['TT'])) {
$GLOBALS['TT']->setTSlogMessage($logTitle . ': ' . $message, $severity + 1);
}
// Write error message to sys_log table (ext: belog, Tools->Log)
$this->writeLog($logTitle . ': ' . $message, $severity);
// Add error message to the flashmessageQueue
if (TYPO3_ERRORHANDLER_MODE == 'debug') {
$flashMessage = t3lib_div::makeInstance(
't3lib_FlashMessage',
$message,
'PHP ' . $errorLevels[$errorLevel],
$severity
);
t3lib_FlashMessageQueue::addMessage($flashMessage);
}
}
// Don't execute PHP internal error handler
return TRUE;
}
/**
* Writes an error in the sys_log table
*
* @param string Default text that follows the message (in english!).
* @param integer The eror level of the message (0 = OK, 1 = warning, 2 = error)
* @return void
*/
protected function writeLog($logMessage, $severity) {
if (is_object($GLOBALS['TYPO3_DB']) && !empty($GLOBALS['TYPO3_DB']->link)) {
$userId = 0;
$workspace = 0;
if (is_object($GLOBALS['BE_USER'])) {
if (isset($GLOBALS['BE_USER']->user['uid'])) {
$userId = $GLOBALS['BE_USER']->user['uid'];
}
if (isset($GLOBALS['BE_USER']->workspace)) {
$workspace = $GLOBALS['BE_USER']->workspace;
}
}
$fields_values = Array (
'userid' => $userId,
'type' => 5,
'action' => 0,
'error' => $severity,
'details_nr' => 0,
'details' => $logMessage,
'IP' => t3lib_div::getIndpEnv('REMOTE_ADDR'),
'tstamp' => $GLOBALS['EXEC_TIME'],
'workspace' => $workspace
);
$GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_log', $fields_values);
}
}
}
typo3/init.php (Arbeitskopie)
// *********************
if ($TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionHandler'] !== '') {
if ($TYPO3_CONF_VARS['SYS']['errorHandler'] !== '') {
$errorHandler = t3lib_div::makeInstance($TYPO3_CONF_VARS['SYS']['errorHandler']);
// register an error handler for the given exceptionalErrors
$errorHandler->setErrorHandlerForExceptionalErrors($TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionalErrors']);
// register an error handler for the given errorHandlerErrors
$errorHandler = t3lib_div::makeInstance($TYPO3_CONF_VARS['SYS']['errorHandler'], $TYPO3_CONF_VARS['SYS']['errorHandlerErrors']);
// set errors which will be converted in an exception
$errorHandler->setExceptionalErrors($TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionalErrors']);
}
$exceptionHandler = t3lib_div::makeInstance($TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionHandler']);
}
typo3/sysext/cms/tslib/index_ts.php (Arbeitskopie)
if ($TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionHandler'] !== '') {
$TT->push('Register Exceptionhandler', '');
if ($TYPO3_CONF_VARS['SYS']['errorHandler'] !== '') {
$errorHandler = t3lib_div::makeInstance($TYPO3_CONF_VARS['SYS']['errorHandler']);
// register an error handler for the given exceptionalErrors
$errorHandler->setErrorHandlerForExceptionalErrors($TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionalErrors']);
// register an error handler for the given errorHandlerErrors
$errorHandler = t3lib_div::makeInstance($TYPO3_CONF_VARS['SYS']['errorHandler'], $TYPO3_CONF_VARS['SYS']['errorHandlerErrors']);
// set errors which will be converted in an exception
$errorHandler->setExceptionalErrors($TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionalErrors']);
}
$exceptionHandler = t3lib_div::makeInstance($TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionHandler']);
$TT->pull();
(1-1/2)