diff --git a/typo3/sysext/core/Classes/Core/Bootstrap.php b/typo3/sysext/core/Classes/Core/Bootstrap.php index 8c88d91465e34679f7209b27fff575c7c5fd948f..ced25503386517d0506f7d5c11d9c66728b9a865 100644 --- a/typo3/sysext/core/Classes/Core/Bootstrap.php +++ b/typo3/sysext/core/Classes/Core/Bootstrap.php @@ -62,16 +62,6 @@ class Bootstrap { */ protected $installToolPath; - /** - * @var string The currently active exception handling class. It is set after LocalConfiguration is included and might be changed after ex_localconf.php are loaded. - */ - protected $activeExceptionHandlerClassName; - - /** - * @var string The currently active error handling class. It is set after LocalConfiguration is included and might be changed after ex_localconf.php are loaded. - */ - protected $activeErrorHandlerClassName; - /** * A list of all registered request handlers, see the Application class / entry points for the registration * @var \TYPO3\CMS\Core\Http\RequestHandlerInterface[]|\TYPO3\CMS\Core\Console\RequestHandlerInterface[] @@ -174,7 +164,6 @@ class Bootstrap { $this->startOutputBuffering() ->loadConfigurationAndInitialize() ->loadTypo3LoadedExtAndExtLocalconf(TRUE) - ->initializeExceptionHandling() ->setFinalCachingFrameworkCacheConfiguration() ->defineLoggingAndExceptionConstants() ->unsetReservedGlobalVariables() @@ -366,7 +355,8 @@ class Bootstrap { * @internal This is not a public API method, do not use in own extensions */ public function loadConfigurationAndInitialize($allowCaching = TRUE, $packageManagerClassName = \TYPO3\CMS\Core\Package\PackageManager::class) { - $this->populateLocalConfiguration(); + $this->populateLocalConfiguration() + ->initializeErrorHandling(); if (!$allowCaching) { $this->disableCoreCache(); } @@ -382,8 +372,6 @@ class Bootstrap { ->initializeL10nLocales() ->convertPageNotFoundHandlingToBoolean() ->registerGlobalDebugFunctions() - ->configureExceptionHandling() - ->initializeExceptionHandling() ->setMemoryLimit() ->defineTypo3RequestTypes(); if ($allowCaching) { @@ -684,29 +672,52 @@ class Bootstrap { * Configure and set up exception and error handling * * @return Bootstrap + * @throws \RuntimeException */ - protected function configureExceptionHandling() { - $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['productionExceptionHandler']; - $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionalErrors'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['exceptionalErrors']; - $doesIpMatch = GeneralUtility::cmpIP(GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask']); - $displayErrors = (int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['displayErrors']; - // Turn error logging on/off. - if ($displayErrors !== -1) { - // Special value "2" enables this feature only if $GLOBALS['TYPO3_CONF_VARS'][SYS][devIPmask] matches - if ($displayErrors === 2) { - $displayErrors = (int)$doesIpMatch; - } - if ($displayErrors === 0) { - $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionalErrors'] = 0; - } - if ($displayErrors === 1) { - $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['debugExceptionHandler']; - define('TYPO3_ERRORHANDLER_MODE', 'debug'); + protected function initializeErrorHandling() { + $productionExceptionHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['productionExceptionHandler']; + $debugExceptionHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['debugExceptionHandler']; + + $errorHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler']; + $errorHandlerErrors = $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandlerErrors']; + $exceptionalErrors = $GLOBALS['TYPO3_CONF_VARS']['SYS']['exceptionalErrors']; + + $displayErrorsSetting = (int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['displayErrors']; + switch ($displayErrorsSetting) { + case 2: + GeneralUtility::deprecationLog('The option "$TYPO3_CONF_VARS[SYS][displayErrors]" is set to "2" which is deprecated as of TYPO3 CMS 7, and will be removed with TYPO3 CMS 8. Please change the value to "-1"'); + // intentionally fall through + case -1: + $ipMatchesDevelopmentSystem = GeneralUtility::cmpIP(GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask']); + $exceptionHandlerClassName = $ipMatchesDevelopmentSystem ? $debugExceptionHandlerClassName : $productionExceptionHandlerClassName; + $displayErrors = $ipMatchesDevelopmentSystem ? 1 : 0; + $exceptionalErrors = $ipMatchesDevelopmentSystem ? $exceptionalErrors : 0; + break; + case 0: + $exceptionHandlerClassName = $productionExceptionHandlerClassName; + $displayErrors = 0; + break; + case 1: + $exceptionHandlerClassName = $debugExceptionHandlerClassName; + $displayErrors = 1; + break; + default: + // Throw exception if an invalid option is set. + throw new \RuntimeException('The option $TYPO3_CONF_VARS[SYS][displayErrors] is not set to "-1", "0" or "1".'); + } + @ini_set('display_errors', $displayErrors); + + if (!empty($errorHandlerClassName)) { + // Register an error handler for the given errorHandlerError + $errorHandler = GeneralUtility::makeInstance($errorHandlerClassName, $errorHandlerErrors); + $errorHandler->setExceptionalErrors($exceptionalErrors); + if (is_callable(array($errorHandler, 'setDebugMode'))) { + $errorHandler->setDebugMode($displayErrors === 1); } - @ini_set('display_errors', $displayErrors); - } elseif ($doesIpMatch) { - // With displayErrors = -1 (default), turn on debugging if devIPmask matches: - $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['debugExceptionHandler']; + } + if (!empty($exceptionHandlerClassName)) { + // Registering the exception handler is done in the constructor + GeneralUtility::makeInstance($exceptionHandlerClassName); } return $this; } @@ -740,41 +751,6 @@ class Bootstrap { return $this; } - /** - * Initialize exception handling - * This method is called twice. First when LocalConfiguration has been loaded - * and a second time after extension ext_localconf.php have been included to allow extensions - * to change the exception and error handler configuration. - * - * @return Bootstrap - * @internal This is not a public API method, do not use in own extensions - */ - public function initializeExceptionHandling() { - if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'])) { - if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler'])) { - if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler'] !== $this->activeErrorHandlerClassName) { - $this->activeErrorHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler']; - // Register an error handler for the given errorHandlerErrors - $errorHandler = GeneralUtility::makeInstance($this->activeErrorHandlerClassName, $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandlerErrors']); - // Set errors which will be converted in an exception - $errorHandler->setExceptionalErrors($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionalErrors']); - } - } elseif (!empty($this->activeErrorHandlerClassName)) { - // Restore error handler in case extensions have unset the configuration in ext_localconf.php - restore_error_handler(); - } - if ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] !== $this->activeExceptionHandlerClassName) { - $this->activeExceptionHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler']; - // Registering the exception handler is done in the constructor - GeneralUtility::makeInstance($this->activeExceptionHandlerClassName); - } - } elseif (!empty($this->activeExceptionHandlerClassName)) { - // Restore exception handler in case extensions have unset the configuration in ext_localconf.php - restore_exception_handler(); - } - return $this; - } - /** * Extensions may register new caches, so we set the * global cache array to the manager again at this point diff --git a/typo3/sysext/core/Classes/Error/ErrorHandler.php b/typo3/sysext/core/Classes/Error/ErrorHandler.php index 2ac8f1d84a1e969c81a714e4388cb9d80b76b953..70deb50c4931da6fb897f57827fa2b4ed16f6e1a 100644 --- a/typo3/sysext/core/Classes/Error/ErrorHandler.php +++ b/typo3/sysext/core/Classes/Error/ErrorHandler.php @@ -32,6 +32,13 @@ class ErrorHandler implements ErrorHandlerInterface { */ protected $exceptionalErrors = array(); + /** + * Whether to write a flash message in case of an error + * + * @var bool + */ + protected $debugMode = FALSE; + /** * Registers this class as default error handler * @@ -54,6 +61,13 @@ class ErrorHandler implements ErrorHandlerInterface { $this->exceptionalErrors = (int)$exceptionalErrors; } + /** + * @param bool $debugMode + */ + public function setDebugMode($debugMode) { + $this->debugMode = (bool)$debugMode; + } + /** * Handles an error. * If the error is registered as exceptionalError it will by converted into an exception, to be handled @@ -135,8 +149,7 @@ class ErrorHandler implements ErrorHandlerInterface { // Let the internal handler continue. This will stop the script return FALSE; } else { - // Add error message to the flashmessageQueue - if (defined('TYPO3_ERRORHANDLER_MODE') && TYPO3_ERRORHANDLER_MODE == 'debug') { + if ($this->debugMode) { /** @var $flashMessage \TYPO3\CMS\Core\Messaging\FlashMessage */ $flashMessage = GeneralUtility::makeInstance( \TYPO3\CMS\Core\Messaging\FlashMessage::class, diff --git a/typo3/sysext/core/Configuration/DefaultConfiguration.php b/typo3/sysext/core/Configuration/DefaultConfiguration.php index 9f53065b01e8e84385af2bd713adecd759507515..046a543eb6f1e5314c7a2a54bf34abea5b2f8dfe 100644 --- a/typo3/sysext/core/Configuration/DefaultConfiguration.php +++ b/typo3/sysext/core/Configuration/DefaultConfiguration.php @@ -223,7 +223,7 @@ return array( ), ), 'defaultCategorizedTables' => 'pages,tt_content,sys_file_metadata', // List of comma separated tables that are categorizable by default. - 'displayErrors' => -1, // <p>Integer (-1, 0, 1, 2). Configures whether PHP errors or Exceptions should be displayed.</p><dl><dt>0</dt><dd>Do not display any PHP error message. Sets PHP "display_errors" setting to 0. Overrides the value of [SYS][exceptionalErrors] and sets it to 0 (= no errors are turned into exceptions). The configured [SYS][productionExceptionHandler] is used as exception handler.</dd><dt>1</dt><dd>Display error messages with the registered [SYS][errorHandler]. Sets PHP "display_errors" setting to 1. The configured [SYS][debugExceptionHandler] is used as exception handler.</dd><dt>2</dt><dd>Lets the [SYS][devIPmask] decide if this setting shall be "1" (user's IP matches) or "0" (IP does not match).</dd><dt>-1</dt><dd>Default setting. TYPO3 CMS does not touch the PHP "display_errors" setting. If [SYS][devIPmask] matches the user's IP address, the configured [SYS][debugExceptionHandler] is used instead of the [SYS][productionExceptionHandler] to handle exceptions.</dd></dl> + 'displayErrors' => -1, // <p>Integer (-1, 0, 1). Configures whether PHP errors or Exceptions should be displayed.</p><dl><dt>0</dt><dd>Do not display any PHP error message. Sets PHP "display_errors" setting to 0. Overrides the value of [SYS][exceptionalErrors] and sets it to 0 (= no errors are turned into exceptions). The configured [SYS][productionExceptionHandler] is used as exception handler.</dd><dt>1</dt><dd>Display error messages with the registered [SYS][errorHandler]. Sets PHP "display_errors" setting to 1. The configured [SYS][debugExceptionHandler] is used as exception handler.</dd><dt>-1</dt><dd>Default setting. TYPO3 CMS does not touch the PHP "display_errors" setting. If [SYS][devIPmask] matches the user's IP address, the configured [SYS][debugExceptionHandler] is used instead of the [SYS][productionExceptionHandler] to handle exceptions.</dd></dl> 'productionExceptionHandler' => \TYPO3\CMS\Core\Error\ProductionExceptionHandler::class, // String: Classname to handle exceptions that might happen in the TYPO3-code. Leave empty to disable exception handling. Default: "TYPO3\\CMS\\Core\\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 [SYS][displayErrors] is set to "0" or is set to "-1" and [SYS][devIPmask] doesn't match the user's IP. 'debugExceptionHandler' => \TYPO3\CMS\Core\Error\DebugExceptionHandler::class, // String: Classname to handle exceptions that might happen in the TYPO3-code. Leave empty to disable exception handling. Default: "TYPO3\\CMS\\Core\\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 [SYS][displayErrors] is set to "1" or is set to "-1" or "2" and the [SYS][devIPmask] matches the user's IP. 'errorHandler' => \TYPO3\CMS\Core\Error\ErrorHandler::class, // String: Classname to handle PHP errors. E.g.: TYPO3\CMS\Core\Error\ErrorHandler. This class displays and logs all errors that are registered as [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 [SYS][exceptionalErrors] it will be turned into an exception to be handled by the configured exceptionHandler. diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-68131-StreamlineErrorAndExceptionHandling.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-68131-StreamlineErrorAndExceptionHandling.rst new file mode 100644 index 0000000000000000000000000000000000000000..c7487cfedae20131c761f5bd2aa505f0e4ebc71d --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Breaking-68131-StreamlineErrorAndExceptionHandling.rst @@ -0,0 +1,26 @@ +========================================================== +Breaking: #68131 - Streamline error and exception handling +========================================================== + +Description +=========== + +It is not possible any more to change error and exception handling configuration in an ext_localconf.php of an extension. + + +Impact +====== + +Error or exception handling configuration overridden in ext_localonf.php files will not work any more. + + +Affected Installations +====================== + +All installations with extension that set error or exception handling configuration in ext_localconf.php files. + + +Migration +========= + +Configure error and exception handling in LocalConfiguration.php or AdditionalConfiguration.php \ No newline at end of file diff --git a/typo3/sysext/core/Tests/FunctionalTestCaseBootstrapUtility.php b/typo3/sysext/core/Tests/FunctionalTestCaseBootstrapUtility.php index 01b15a7da09b4def2f31a884296b59f4cddfccb3..3b785fe34cc366fe9983e531b4408fe1e0cc7a0f 100644 --- a/typo3/sysext/core/Tests/FunctionalTestCaseBootstrapUtility.php +++ b/typo3/sysext/core/Tests/FunctionalTestCaseBootstrapUtility.php @@ -433,7 +433,6 @@ class FunctionalTestCaseBootstrapUtility { ->baseSetup('') ->loadConfigurationAndInitialize(TRUE) ->loadTypo3LoadedExtAndExtLocalconf(TRUE) - ->initializeExceptionHandling() ->setFinalCachingFrameworkCacheConfiguration() ->defineLoggingAndExceptionConstants() ->unsetReservedGlobalVariables(); diff --git a/typo3/sysext/install/Classes/Controller/Action/AbstractAction.php b/typo3/sysext/install/Classes/Controller/Action/AbstractAction.php index b39378e2e0cac84b53c422662d0342200cd82d5d..50aa66c0c83e9f2b56ef82b2d65db1b15d036385 100644 --- a/typo3/sysext/install/Classes/Controller/Action/AbstractAction.php +++ b/typo3/sysext/install/Classes/Controller/Action/AbstractAction.php @@ -248,7 +248,6 @@ abstract class AbstractAction implements ActionInterface { \TYPO3\CMS\Core\Core\Bootstrap::getInstance() ->ensureClassLoadingInformationExists() ->loadTypo3LoadedExtAndExtLocalconf(FALSE) - ->initializeExceptionHandling() ->defineLoggingAndExceptionConstants() ->unsetReservedGlobalVariables() ->initializeTypo3DbGlobal() diff --git a/typo3/sysext/install/Classes/Service/ClearCacheService.php b/typo3/sysext/install/Classes/Service/ClearCacheService.php index f7c480e03e25a566cf2f55631c87cdc66a2e4ce9..3d0848dd4b7e7ae1660fe782c5e33b1f5b407348 100644 --- a/typo3/sysext/install/Classes/Service/ClearCacheService.php +++ b/typo3/sysext/install/Classes/Service/ClearCacheService.php @@ -74,7 +74,6 @@ class ClearCacheService { // Use bootstrap to load all ext_localconf and ext_tables $bootstrap ->loadTypo3LoadedExtAndExtLocalconf(FALSE) - ->initializeExceptionHandling() ->defineLoggingAndExceptionConstants() ->unsetReservedGlobalVariables() ->initializeTypo3DbGlobal()