[!!!][FEATURE] Introduce PSR-3 Logging
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Error / ErrorHandler.php
index 2bd87a3..e82acf5 100644 (file)
@@ -18,6 +18,8 @@ use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerAwareTrait;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Log\LogLevel;
+use TYPO3\CMS\Core\Log\LogManager;
+use TYPO3\CMS\Core\Messaging\FlashMessage;
 use TYPO3\CMS\Core\TimeTracker\TimeTracker;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
@@ -38,6 +40,13 @@ class ErrorHandler implements ErrorHandlerInterface, LoggerAwareInterface
     protected $exceptionalErrors = 0;
 
     /**
+     * Error levels which should be handled.
+     *
+     * @var int
+     */
+    protected $errorHandlerErrors = 0;
+
+    /**
      * Whether to write a flash message in case of an error
      *
      * @var bool
@@ -53,8 +62,8 @@ class ErrorHandler implements ErrorHandlerInterface, LoggerAwareInterface
     {
         $excludedErrors = E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR;
         // reduces error types to those a custom error handler can process
-        $errorHandlerErrors = $errorHandlerErrors & ~$excludedErrors;
-        set_error_handler([$this, 'handleError'], $errorHandlerErrors);
+        $this->errorHandlerErrors = $errorHandlerErrors & ~$excludedErrors;
+        set_error_handler([$this, 'handleError'], $this->errorHandlerErrors);
     }
 
     /**
@@ -64,7 +73,10 @@ class ErrorHandler implements ErrorHandlerInterface, LoggerAwareInterface
      */
     public function setExceptionalErrors($exceptionalErrors)
     {
-        $this->exceptionalErrors = (int)$exceptionalErrors;
+        $exceptionalErrors = (int)$exceptionalErrors;
+        // We always disallow E_USER_DEPRECATED to generate exceptions as this may cause
+        // bad user experience specifically during upgrades.
+        $this->exceptionalErrors = $exceptionalErrors & ~E_USER_DEPRECATED;
     }
 
     /**
@@ -91,8 +103,9 @@ class ErrorHandler implements ErrorHandlerInterface, LoggerAwareInterface
      */
     public function handleError($errorLevel, $errorMessage, $errorFile, $errorLine)
     {
-        // Don't do anything if error_reporting is disabled by an @ sign
-        if (error_reporting() === 0) {
+        // Don't do anything if error_reporting is disabled by an @ sign or $errorLevel is something we won't handle
+        $shouldHandleErrorLevel = (bool)($this->errorHandlerErrors & $errorLevel);
+        if (error_reporting() === 0 || !$shouldHandleErrorLevel) {
             return true;
         }
         $errorLevels = [
@@ -113,22 +126,29 @@ class ErrorHandler implements ErrorHandlerInterface, LoggerAwareInterface
         switch ($errorLevel) {
             case E_USER_ERROR:
             case E_RECOVERABLE_ERROR:
+                // no $flashMessageSeverity, as there will be no flash message for errors
                 $severity = 2;
                 break;
             case E_USER_WARNING:
             case E_WARNING:
-            case E_USER_DEPRECATED:
+                $flashMessageSeverity = FlashMessage::WARNING;
                 $severity = 1;
                 break;
             default:
+                $flashMessageSeverity = FlashMessage::NOTICE;
                 $severity = 0;
         }
         $logTitle = 'Core: Error handler (' . TYPO3_MODE . ')';
         $message = $logTitle . ': ' . $message;
 
-        $this->logger->log(LogLevel::NOTICE - $severity, $message);
-        // Write error message to devlog extension(s),
-        GeneralUtility::devLog($message, 'core', $severity + 1);
+        if ($errorLevel === E_USER_DEPRECATED) {
+            $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger('TYPO3.CMS.deprecations');
+            $logger->notice($message);
+            return true;
+        }
+        if ($this->logger) {
+            $this->logger->log(LogLevel::normalizeLevel(LogLevel::NOTICE) - $severity, $message);
+        }
 
         // Write error message to TSlog (admin panel)
         $timeTracker = $this->getTimeTracker();
@@ -148,16 +168,16 @@ class ErrorHandler implements ErrorHandlerInterface, LoggerAwareInterface
             return false;
         }
         if ($this->debugMode) {
-            /** @var $flashMessage \TYPO3\CMS\Core\Messaging\FlashMessage */
+            /** @var \TYPO3\CMS\Core\Messaging\FlashMessage $flashMessage */
             $flashMessage = GeneralUtility::makeInstance(
-                        \TYPO3\CMS\Core\Messaging\FlashMessage::class,
-                        $message,
-                        $errorLevels[$errorLevel],
-                        $severity
+                \TYPO3\CMS\Core\Messaging\FlashMessage::class,
+                $message,
+                $errorLevels[$errorLevel],
+                $flashMessageSeverity
                     );
-            /** @var $flashMessageService \TYPO3\CMS\Core\Messaging\FlashMessageService */
+            /** @var \TYPO3\CMS\Core\Messaging\FlashMessageService $flashMessageService */
             $flashMessageService = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessageService::class);
-            /** @var $defaultFlashMessageQueue \TYPO3\CMS\Core\Messaging\FlashMessageQueue */
+            /** @var \TYPO3\CMS\Core\Messaging\FlashMessageQueue $defaultFlashMessageQueue */
             $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
             $defaultFlashMessageQueue->enqueue($flashMessage);
         }
@@ -201,7 +221,7 @@ class ErrorHandler implements ErrorHandlerInterface, LoggerAwareInterface
                     'error' => $severity,
                     'details_nr' => 0,
                     'details' => str_replace('%', '%%', $logMessage),
-                    'log_data' => (empty($data) ? '' : serialize($data)),
+                    'log_data' => empty($data) ? '' : serialize($data),
                     'IP' => (string)GeneralUtility::getIndpEnv('REMOTE_ADDR'),
                     'tstamp' => $GLOBALS['EXEC_TIME'],
                     'workspace' => $workspace