TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
ErrorHandler.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\Error;
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 
20 
27 {
33  protected $exceptionalErrors = [];
34 
40  protected $debugMode = false;
41 
47  public function __construct($errorHandlerErrors)
48  {
49  $excludedErrors = E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR;
50  // reduces error types to those a custom error handler can process
51  $errorHandlerErrors = $errorHandlerErrors & ~$excludedErrors;
52  set_error_handler([$this, 'handleError'], $errorHandlerErrors);
53  }
54 
62  {
63  $this->exceptionalErrors = (int)$exceptionalErrors;
64  }
65 
69  public function setDebugMode($debugMode)
70  {
71  $this->debugMode = (bool)$debugMode;
72  }
73 
88  public function handleError($errorLevel, $errorMessage, $errorFile, $errorLine)
89  {
90  // Don't do anything if error_reporting is disabled by an @ sign
91  if (error_reporting() === 0) {
92  return true;
93  }
94  $errorLevels = [
95  E_WARNING => 'Warning',
96  E_NOTICE => 'Notice',
97  E_USER_ERROR => 'User Error',
98  E_USER_WARNING => 'User Warning',
99  E_USER_NOTICE => 'User Notice',
100  E_STRICT => 'Runtime Notice',
101  E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
102  E_DEPRECATED => 'Runtime Deprecation Notice'
103  ];
104  $message = 'PHP ' . $errorLevels[$errorLevel] . ': ' . $errorMessage . ' in ' . $errorFile . ' line ' . $errorLine;
105  if ($errorLevel & $this->exceptionalErrors) {
106  // handle error raised at early parse time
107  // autoloader not available & built-in classes not resolvable
108  if (!class_exists('stdClass', false)) {
109  $message = 'PHP ' . $errorLevels[$errorLevel] . ': ' . $errorMessage . ' in ' . basename($errorFile) .
110  'line ' . $errorLine;
111  die($message);
112  }
113  throw new Exception($message, 1476107295);
114  } else {
115  switch ($errorLevel) {
116  case E_USER_ERROR:
117  case E_RECOVERABLE_ERROR:
118  $severity = 2;
119  break;
120  case E_USER_WARNING:
121  case E_WARNING:
122  $severity = 1;
123  break;
124  default:
125  $severity = 0;
126  }
127  $logTitle = 'Core: Error handler (' . TYPO3_MODE . ')';
128  $message = $logTitle . ': ' . $message;
129  // Write error message to the configured syslogs,
130  // see: $TYPO3_CONF_VARS['SYS']['systemLog']
131  if ($errorLevel & $GLOBALS['TYPO3_CONF_VARS']['SYS']['syslogErrorReporting']) {
132  GeneralUtility::sysLog($message, 'core', $severity + 1);
133  }
134  // Write error message to devlog extension(s),
135  // see: $TYPO3_CONF_VARS['SYS']['enable_errorDLOG']
136  if (TYPO3_ERROR_DLOG) {
137  GeneralUtility::devLog($message, 'core', $severity + 1);
138  }
139  // Write error message to TSlog (admin panel)
140  $timeTracker = $this->getTimeTracker();
141  if (is_object($timeTracker)) {
142  $timeTracker->setTSlogMessage($message, $severity + 1);
143  }
144  // Write error message to sys_log table (ext: belog, Tools->Log)
145  if ($errorLevel & $GLOBALS['TYPO3_CONF_VARS']['SYS']['belogErrorReporting']) {
146  // Silently catch in case an error occurs before a database connection exists,
147  // but DatabaseConnection fails to connect.
148  try {
149  $this->writeLog($message, $severity);
150  } catch (\Exception $e) {
151  }
152  }
153  if ($severity === 2) {
154  // Let the internal handler continue. This will stop the script
155  return false;
156  } else {
157  if ($this->debugMode) {
159  $flashMessage = GeneralUtility::makeInstance(
160  \TYPO3\CMS\Core\Messaging\FlashMessage::class,
161  $message,
162  'PHP ' . $errorLevels[$errorLevel],
163  $severity
164  );
166  $flashMessageService = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessageService::class);
168  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
169  $defaultFlashMessageQueue->enqueue($flashMessage);
170  }
171  // Don't execute PHP internal error handler
172  return true;
173  }
174  }
175  }
176 
184  protected function writeLog($logMessage, $severity)
185  {
186  $connection = GeneralUtility::makeInstance(ConnectionPool::class)
187  ->getConnectionForTable('sys_log');
188  if ($connection->isConnected()) {
189  $userId = 0;
190  $workspace = 0;
191  $data = [];
192  $backendUser = $this->getBackendUser();
193  if (is_object($backendUser)) {
194  if (isset($backendUser->user['uid'])) {
195  $userId = $backendUser->user['uid'];
196  }
197  if (isset($backendUser->workspace)) {
198  $workspace = $backendUser->workspace;
199  }
200  if (!empty($backendUser->user['ses_backuserid'])) {
201  $data['originalUser'] = $backendUser->user['ses_backuserid'];
202  }
203  }
204 
205  $connection->insert(
206  'sys_log',
207  [
208  'userid' => $userId,
209  'type' => 5,
210  'action' => 0,
211  'error' => $severity,
212  'details_nr' => 0,
213  'details' => str_replace('%', '%%', $logMessage),
214  'log_data' => (empty($data) ? '' : serialize($data)),
215  'IP' => (string)GeneralUtility::getIndpEnv('REMOTE_ADDR'),
216  'tstamp' => $GLOBALS['EXEC_TIME'],
217  'workspace' => $workspace
218  ]
219  );
220  }
221  }
222 
226  protected function getTimeTracker()
227  {
228  return GeneralUtility::makeInstance(TimeTracker::class);
229  }
230 
234  protected function getBackendUser()
235  {
236  return $GLOBALS['BE_USER'];
237  }
238 }
__construct($errorHandlerErrors)
writeLog($logMessage, $severity)
setExceptionalErrors($exceptionalErrors)
handleError($errorLevel, $errorMessage, $errorFile, $errorLine)
if(TYPO3_MODE=== 'BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static makeInstance($className,...$constructorArguments)
static devLog($msg, $extKey, $severity=0, $dataVar=false)