TYPO3 CMS  TYPO3_8-7
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 
20 
27 {
28  const CONTEXT_WEB = 'WEB';
29  const CONTEXT_CLI = 'CLI';
30 
38  public function handleException(\Throwable $exception)
39  {
40  switch (PHP_SAPI) {
41  case 'cli':
42  $this->echoExceptionCLI($exception);
43  break;
44  default:
45  $this->echoExceptionWeb($exception);
46  }
47  }
48 
56  protected function writeLogEntries(\Throwable $exception, $context)
57  {
58  // Do not write any logs for this message to avoid filling up tables or files with illegal requests
59  if ($exception->getCode() === 1396795884) {
60  return;
61  }
62  $filePathAndName = $exception->getFile();
63  $exceptionCodeNumber = $exception->getCode() > 0 ? '#' . $exception->getCode() . ': ' : '';
64  $logTitle = 'Core: Exception handler (' . $context . ')';
65  $logMessage = 'Uncaught TYPO3 Exception: ' . $exceptionCodeNumber . $exception->getMessage() . ' | '
66  . get_class($exception) . ' thrown in file ' . $filePathAndName . ' in line ' . $exception->getLine();
67  if ($context === 'WEB') {
68  $logMessage .= '. Requested URL: ' . $this->anonymizeToken(GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL'));
69  }
70  $backtrace = $exception->getTrace();
71  // Write error message to the configured syslogs
72  GeneralUtility::sysLog($logMessage, $logTitle, GeneralUtility::SYSLOG_SEVERITY_FATAL);
73  // When database credentials are wrong, the exception is probably
74  // caused by this. Therefor we cannot do any database operation,
75  // otherwise this will lead into recurring exceptions.
76  try {
77  // Write error message to devlog
78  GeneralUtility::devLog($logMessage, $logTitle, 3, [
79  'TYPO3_MODE' => TYPO3_MODE,
80  'backtrace' => $backtrace
81  ]);
82  // Write error message to sys_log table
83  $this->writeLog($logTitle . ': ' . $logMessage);
84  } catch (\Exception $exception) {
85  }
86  }
87 
93  protected function writeLog($logMessage)
94  {
95  $connection = GeneralUtility::makeInstance(ConnectionPool::class)
96  ->getConnectionForTable('sys_log');
97 
98  if (!$connection->isConnected()) {
99  return;
100  }
101  $userId = 0;
102  $workspace = 0;
103  $data = [];
104  $backendUser = $this->getBackendUser();
105  if (is_object($backendUser)) {
106  if (isset($backendUser->user['uid'])) {
107  $userId = $backendUser->user['uid'];
108  }
109  if (isset($backendUser->workspace)) {
110  $workspace = $backendUser->workspace;
111  }
112  if (!empty($backendUser->user['ses_backuserid'])) {
113  $data['originalUser'] = $backendUser->user['ses_backuserid'];
114  }
115  }
116 
117  $connection->insert(
118  'sys_log',
119  [
120  'userid' => $userId,
121  'type' => 5,
122  'action' => 0,
123  'error' => 2,
124  'details_nr' => 0,
125  'details' => str_replace('%', '%%', $logMessage),
126  'log_data' => empty($data) ? '' : serialize($data),
127  'IP' => (string)GeneralUtility::getIndpEnv('REMOTE_ADDR'),
128  'tstamp' => $GLOBALS['EXEC_TIME'],
129  'workspace' => $workspace
130  ]
131  );
132  }
133 
140  protected function sendStatusHeaders(\Throwable $exception)
141  {
142  if (method_exists($exception, 'getStatusHeaders')) {
143  $headers = $exception->getStatusHeaders();
144  } else {
145  $headers = [HttpUtility::HTTP_STATUS_500];
146  }
147  if (!headers_sent()) {
148  foreach ($headers as $header) {
149  header($header);
150  }
151  }
152  }
153 
157  protected function getBackendUser()
158  {
159  return $GLOBALS['BE_USER'];
160  }
161 
168  protected function anonymizeToken(string $requestedUrl): string
169  {
170  $pattern = '/(?<=[tT]oken=)[0-9a-fA-F]{40}/';
171  return preg_replace($pattern, '--AnonymizedToken--', $requestedUrl);
172  }
173 }
static devLog($msg, $extKey, $severity=0, $dataVar=false)
static makeInstance($className,... $constructorArguments)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']