‪TYPO3CMS  9.5
ErrorHandler.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
17 use Psr\Log\LoggerAwareInterface;
18 use Psr\Log\LoggerAwareTrait;
25 
31 class ‪ErrorHandler implements ‪ErrorHandlerInterface, LoggerAwareInterface
32 {
33  use LoggerAwareTrait;
34 
40  protected ‪$exceptionalErrors = 0;
41 
47  protected ‪$errorHandlerErrors = 0;
48 
54  protected ‪$debugMode = false;
55 
61  public function ‪__construct(‪$errorHandlerErrors)
62  {
63  $excludedErrors = E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR;
64  // reduces error types to those a custom error handler can process
65  $this->errorHandlerErrors = (int)‪$errorHandlerErrors & ~$excludedErrors;
66  }
67 
74  {
76  // We always disallow E_USER_DEPRECATED to generate exceptions as this may cause
77  // bad user experience specifically during upgrades.
78  $this->exceptionalErrors = ‪$exceptionalErrors & ~E_USER_DEPRECATED;
79  }
80 
84  public function ‪setDebugMode(‪$debugMode)
85  {
86  $this->debugMode = (bool)‪$debugMode;
87  }
88 
89  public function ‪registerErrorHandler()
90  {
91  set_error_handler([$this, 'handleError'], $this->errorHandlerErrors);
92  }
93 
108  public function ‪handleError($errorLevel, $errorMessage, $errorFile, $errorLine)
109  {
110  // Don't do anything if error_reporting is disabled by an @ sign or $errorLevel is something we won't handle
111  $shouldHandleErrorLevel = (bool)($this->errorHandlerErrors & $errorLevel);
112  if (error_reporting() === 0 || !$shouldHandleErrorLevel) {
113  return true;
114  }
115  $errorLevels = [
116  E_WARNING => 'PHP Warning',
117  E_NOTICE => 'PHP Notice',
118  E_USER_ERROR => 'PHP User Error',
119  E_USER_WARNING => 'PHP User Warning',
120  E_USER_NOTICE => 'PHP User Notice',
121  E_STRICT => 'PHP Runtime Notice',
122  E_RECOVERABLE_ERROR => 'PHP Catchable Fatal Error',
123  E_USER_DEPRECATED => 'TYPO3 Deprecation Notice',
124  E_DEPRECATED => 'PHP Runtime Deprecation Notice'
125  ];
126  $message = $errorLevels[$errorLevel] . ': ' . $errorMessage . ' in ' . $errorFile . ' line ' . $errorLine;
127  if ($errorLevel & $this->exceptionalErrors) {
128  throw new Exception($message, 1476107295);
129  }
130  switch ($errorLevel) {
131  case E_USER_ERROR:
132  case E_RECOVERABLE_ERROR:
133  // no $flashMessageSeverity, as there will be no flash message for errors
134  $severity = 2;
135  break;
136  case E_USER_WARNING:
137  case E_WARNING:
138  $flashMessageSeverity = ‪FlashMessage::WARNING;
139  $severity = 1;
140  break;
141  default:
142  $flashMessageSeverity = ‪FlashMessage::NOTICE;
143  $severity = 0;
144  }
145  $logTitle = 'Core: Error handler (' . TYPO3_MODE . ')';
146  $message = $logTitle . ': ' . $message;
147 
148  if ($errorLevel === E_USER_DEPRECATED) {
149  $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger('TYPO3.CMS.deprecations');
150  $logger->notice($message);
151  return true;
152  }
153  if ($this->logger) {
154  $this->logger->log(‪LogLevel::NOTICE - $severity, $message);
155  }
156 
157  // Write error message to TSlog (admin panel)
158  $timeTracker = $this->‪getTimeTracker();
159  if (is_object($timeTracker)) {
160  $timeTracker->setTSlogMessage($message, $severity + 1);
161  }
162  // Write error message to sys_log table (ext: belog, Tools->Log)
163  if ($errorLevel & ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['belogErrorReporting']) {
164  // Silently catch in case an error occurs before a database connection exists.
165  try {
166  $this->‪writeLog($message, $severity);
167  } catch (\Exception $e) {
168  }
169  }
170  if ($severity === 2) {
171  // Let the internal handler continue. This will stop the script
172  return false;
173  }
174  if ($this->debugMode) {
176  $flashMessage = GeneralUtility::makeInstance(
177  \‪TYPO3\CMS\Core\Messaging\FlashMessage::class,
178  $message,
179  $errorLevels[$errorLevel],
180  $flashMessageSeverity
181  );
183  $flashMessageService = GeneralUtility::makeInstance(\‪TYPO3\CMS\Core\Messaging\FlashMessageService::class);
185  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
186  $defaultFlashMessageQueue->enqueue($flashMessage);
187  }
188  // Don't execute PHP internal error handler
189  return true;
190  }
191 
198  protected function ‪writeLog($logMessage, $severity)
199  {
200  $connection = GeneralUtility::makeInstance(ConnectionPool::class)
201  ->getConnectionForTable('sys_log');
202  if ($connection->isConnected()) {
203  $userId = 0;
204  $workspace = 0;
205  $data = [];
206  $backendUser = $this->‪getBackendUser();
207  if (is_object($backendUser)) {
208  if (isset($backendUser->user['uid'])) {
209  $userId = $backendUser->user['uid'];
210  }
211  if (isset($backendUser->workspace)) {
212  $workspace = $backendUser->workspace;
213  }
214  if (!empty($backendUser->user['ses_backuserid'])) {
215  $data['originalUser'] = $backendUser->user['ses_backuserid'];
216  }
217  }
218 
219  $connection->insert(
220  'sys_log',
221  [
222  'userid' => $userId,
223  'type' => 5,
224  'action' => 0,
225  'error' => $severity,
226  'details_nr' => 0,
227  'details' => str_replace('%', '%%', $logMessage),
228  'log_data' => empty($data) ? '' : serialize($data),
229  'IP' => (string)GeneralUtility::getIndpEnv('REMOTE_ADDR'),
230  'tstamp' => ‪$GLOBALS['EXEC_TIME'],
231  'workspace' => $workspace
232  ]
233  );
234  }
235  }
236 
240  protected function ‪getTimeTracker()
241  {
242  return GeneralUtility::makeInstance(TimeTracker::class);
243  }
244 
248  protected function ‪getBackendUser()
249  {
250  return ‪$GLOBALS['BE_USER'];
251  }
252 }
‪TYPO3\CMS\Core\Error\ErrorHandler\writeLog
‪writeLog($logMessage, $severity)
Definition: ErrorHandler.php:195
‪TYPO3\CMS\Core\Error\ErrorHandler\$debugMode
‪bool $debugMode
Definition: ErrorHandler.php:51
‪TYPO3
‪TYPO3\CMS\Core\Error\ErrorHandler\$errorHandlerErrors
‪int $errorHandlerErrors
Definition: ErrorHandler.php:45
‪TYPO3\CMS\Core\Error\ErrorHandler\$exceptionalErrors
‪int $exceptionalErrors
Definition: ErrorHandler.php:39
‪TYPO3\CMS\Core\Error\ErrorHandler\setExceptionalErrors
‪setExceptionalErrors($exceptionalErrors)
Definition: ErrorHandler.php:70
‪TYPO3\CMS\Core\Messaging\AbstractMessage\WARNING
‪const WARNING
Definition: AbstractMessage.php:28
‪TYPO3\CMS\Core\Error\ErrorHandlerInterface
Definition: ErrorHandlerInterface.php:23
‪TYPO3\CMS\Core\Error\ErrorHandler\__construct
‪__construct($errorHandlerErrors)
Definition: ErrorHandler.php:58
‪TYPO3\CMS\Core\Error\ErrorHandler\setDebugMode
‪setDebugMode($debugMode)
Definition: ErrorHandler.php:81
‪TYPO3\CMS\Core\Error\ErrorHandler\getTimeTracker
‪TimeTracker getTimeTracker()
Definition: ErrorHandler.php:237
‪TYPO3\CMS\Core\Error\ErrorHandler\registerErrorHandler
‪registerErrorHandler()
Definition: ErrorHandler.php:86
‪TYPO3\CMS\Core\Error\ErrorHandler\handleError
‪bool handleError($errorLevel, $errorMessage, $errorFile, $errorLine)
Definition: ErrorHandler.php:105
‪TYPO3\CMS\Core\Error\Exception
Definition: Exception.php:21
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:22
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Log\LogManager
Definition: LogManager.php:25
‪TYPO3\CMS\Core\Error
Definition: AbstractExceptionHandler.php:2
‪TYPO3\CMS\Core\Messaging\AbstractMessage\NOTICE
‪const NOTICE
Definition: AbstractMessage.php:25
‪TYPO3\CMS\Core\Error\ErrorHandler\getBackendUser
‪TYPO3 CMS Core Authentication BackendUserAuthentication getBackendUser()
Definition: ErrorHandler.php:245
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:44
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Core\Log\LogLevel\NOTICE
‪const NOTICE
Definition: LogLevel.php:76
‪TYPO3\CMS\Core\TimeTracker\TimeTracker
Definition: TimeTracker.php:27
‪TYPO3\CMS\Core\Log\LogLevel
Definition: LogLevel.php:21
‪TYPO3\CMS\Core\Error\ErrorHandler
Definition: ErrorHandler.php:32