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