TYPO3 CMS  TYPO3_7-6
AbstractExceptionHandler.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 
19 
26 {
27  const CONTEXT_WEB = 'WEB';
28  const CONTEXT_CLI = 'CLI';
29 
38  public function handleException($exception)
39  {
40  if ($exception instanceof \Throwable || $exception instanceof \Exception) {
41  switch (PHP_SAPI) {
42  case 'cli':
43  $this->echoExceptionCLI($exception);
44  break;
45  default:
46  $this->echoExceptionWeb($exception);
47  }
48  } else {
49  throw new \Exception('handleException was called the wrong way.', 1450714322);
50  }
51  }
52 
62  protected function writeLogEntries($exception, $context)
63  {
64  // Do not write any logs for this message to avoid filling up tables or files with illegal requests
65  if ($exception->getCode() === 1396795884) {
66  return;
67  }
68  $filePathAndName = $exception->getFile();
69  $exceptionCodeNumber = $exception->getCode() > 0 ? '#' . $exception->getCode() . ': ' : '';
70  $logTitle = 'Core: Exception handler (' . $context . ')';
71  $logMessage = 'Uncaught TYPO3 Exception: ' . $exceptionCodeNumber . $exception->getMessage() . ' | '
72  . get_class($exception) . ' thrown in file ' . $filePathAndName . ' in line ' . $exception->getLine();
73  if ($context === 'WEB') {
74  $logMessage .= '. Requested URL: ' . $this->anonymizeToken(GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL'));
75  }
76  $backtrace = $exception->getTrace();
77  // Write error message to the configured syslogs
78  GeneralUtility::sysLog($logMessage, $logTitle, GeneralUtility::SYSLOG_SEVERITY_FATAL);
79  // When database credentials are wrong, the exception is probably
80  // caused by this. Therefor we cannot do any database operation,
81  // otherwise this will lead into recurring exceptions.
82  try {
83  // Write error message to devlog
84  // see: $TYPO3_CONF_VARS['SYS']['enable_exceptionDLOG']
85  if (TYPO3_EXCEPTION_DLOG) {
86  GeneralUtility::devLog($logMessage, $logTitle, 3, [
87  'TYPO3_MODE' => TYPO3_MODE,
88  'backtrace' => $backtrace
89  ]);
90  }
91  // Write error message to sys_log table
92  $this->writeLog($logTitle . ': ' . $logMessage);
93  } catch (\Exception $exception) {
94  }
95  }
96 
103  protected function writeLog($logMessage)
104  {
105  $databaseConnection = $this->getDatabaseConnection();
106  if (!is_object($databaseConnection) || !$databaseConnection->isConnected()) {
107  return;
108  }
109  $userId = 0;
110  $workspace = 0;
111  $data = [];
112  $backendUser = $this->getBackendUser();
113  if (is_object($backendUser)) {
114  if (isset($backendUser->user['uid'])) {
115  $userId = $backendUser->user['uid'];
116  }
117  if (isset($backendUser->workspace)) {
118  $workspace = $backendUser->workspace;
119  }
120  if (!empty($backendUser->user['ses_backuserid'])) {
121  $data['originalUser'] = $backendUser->user['ses_backuserid'];
122  }
123  }
124  $fields_values = [
125  'userid' => $userId,
126  'type' => 5,
127  'action' => 0,
128  'error' => 2,
129  'details_nr' => 0,
130  'details' => str_replace('%', '%%', $logMessage),
131  'log_data' => (empty($data) ? '' : serialize($data)),
132  'IP' => (string)GeneralUtility::getIndpEnv('REMOTE_ADDR'),
133  'tstamp' => $GLOBALS['EXEC_TIME'],
134  'workspace' => $workspace
135  ];
136  $databaseConnection->exec_INSERTquery('sys_log', $fields_values);
137  }
138 
147  protected function sendStatusHeaders($exception)
148  {
149  if (method_exists($exception, 'getStatusHeaders')) {
150  $headers = $exception->getStatusHeaders();
151  } else {
152  $headers = [HttpUtility::HTTP_STATUS_500];
153  }
154  if (!headers_sent()) {
155  foreach ($headers as $header) {
156  header($header);
157  }
158  }
159  }
160 
161  /*
162  * Replaces the generated token with a generic equivalent
163  *
164  * @param string $requestedUrl
165  * @return string
166  */
167  protected function anonymizeToken($requestedUrl)
168  {
169  $pattern = '/(?<=[tT]oken=)[0-9a-fA-F]{40}/';
170  return preg_replace($pattern, '--AnonymizedToken--', $requestedUrl);
171  }
172 
176  protected function getBackendUser()
177  {
178  return $GLOBALS['BE_USER'];
179  }
180 
185  protected function getDatabaseConnection()
186  {
187  return $GLOBALS['TYPO3_DB'];
188  }
189 }
static devLog($msg, $extKey, $severity=0, $dataVar=false)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']