94b58022882bcafe15ef8b46c5f1db47c170c636
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Error / AbstractExceptionHandler.php
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 use TYPO3\CMS\Core\Utility\GeneralUtility;
17
18 /**
19 * An abstract exception handler
20 *
21 * This file is a backport from FLOW3
22 *
23 * @author Ingo Renner <ingo@typo3.org>
24 */
25 abstract class AbstractExceptionHandler implements ExceptionHandlerInterface, \TYPO3\CMS\Core\SingletonInterface {
26
27 const CONTEXT_WEB = 'WEB';
28 const CONTEXT_CLI = 'CLI';
29
30 /**
31 * Displays the given exception
32 *
33 * @param \Exception $exception The exception object
34 * @return void
35 */
36 public function handleException(\Exception $exception) {
37 switch (PHP_SAPI) {
38 case 'cli':
39 $this->echoExceptionCLI($exception);
40 break;
41 default:
42 $this->echoExceptionWeb($exception);
43 }
44 }
45
46 /**
47 * Writes exception to different logs
48 *
49 * @param \Exception $exception The exception
50 * @param string $context The context where the exception was thrown, WEB or CLI
51 * @return void
52 * @see \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog(), \TYPO3\CMS\Core\Utility\GeneralUtility::devLog()
53 */
54 protected function writeLogEntries(\Exception $exception, $context) {
55 // Do not write any logs for this message to avoid filling up tables or files with illegal requests
56 if ($exception->getCode() === 1396795884) {
57 return;
58 }
59 $filePathAndName = $exception->getFile();
60 $exceptionCodeNumber = $exception->getCode() > 0 ? '#' . $exception->getCode() . ': ' : '';
61 $logTitle = 'Core: Exception handler (' . $context . ')';
62 $logMessage = 'Uncaught TYPO3 Exception: ' . $exceptionCodeNumber . $exception->getMessage() . ' | '
63 . get_class($exception) . ' thrown in file ' . $filePathAndName . ' in line ' . $exception->getLine();
64 if ($context === 'WEB') {
65 $logMessage .= '. Requested URL: ' . GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL');
66 }
67 $backtrace = $exception->getTrace();
68 // Write error message to the configured syslogs
69 GeneralUtility::sysLog($logMessage, $logTitle, GeneralUtility::SYSLOG_SEVERITY_FATAL);
70 // When database credentials are wrong, the exception is probably
71 // caused by this. Therefor we cannot do any database operation,
72 // otherwise this will lead into recurring exceptions.
73 try {
74 // Write error message to devlog
75 // see: $TYPO3_CONF_VARS['SYS']['enable_exceptionDLOG']
76 if (TYPO3_EXCEPTION_DLOG) {
77 GeneralUtility::devLog($logMessage, $logTitle, 3, array(
78 'TYPO3_MODE' => TYPO3_MODE,
79 'backtrace' => $backtrace
80 ));
81 }
82 // Write error message to sys_log table
83 $this->writeLog($logTitle . ': ' . $logMessage);
84 } catch (\Exception $exception) {
85
86 }
87 }
88
89 /**
90 * Writes an exception in the sys_log table
91 *
92 * @param string $logMessage Default text that follows the message.
93 * @return void
94 */
95 protected function writeLog($logMessage) {
96 if (is_object($GLOBALS['TYPO3_DB']) && !empty($GLOBALS['TYPO3_DB']->link)) {
97 $userId = 0;
98 $workspace = 0;
99 if (is_object($GLOBALS['BE_USER'])) {
100 if (isset($GLOBALS['BE_USER']->user['uid'])) {
101 $userId = $GLOBALS['BE_USER']->user['uid'];
102 }
103 if (isset($GLOBALS['BE_USER']->workspace)) {
104 $workspace = $GLOBALS['BE_USER']->workspace;
105 }
106 }
107 $fields_values = array(
108 'userid' => $userId,
109 'type' => 5,
110 'action' => 0,
111 'error' => 2,
112 'details_nr' => 0,
113 'details' => str_replace('%', '%%', $logMessage),
114 'IP' => GeneralUtility::getIndpEnv('REMOTE_ADDR'),
115 'tstamp' => $GLOBALS['EXEC_TIME'],
116 'workspace' => $workspace
117 );
118 $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_log', $fields_values);
119 }
120 }
121
122 /**
123 * Sends the HTTP Status 500 code, if $exception is *not* a
124 * TYPO3\CMS\Core\Error\Http\StatusException and headers are not sent, yet.
125 *
126 * @param \Exception $exception
127 * @return void
128 */
129 protected function sendStatusHeaders(\Exception $exception) {
130 if (method_exists($exception, 'getStatusHeaders')) {
131 $headers = $exception->getStatusHeaders();
132 } else {
133 $headers = array(\TYPO3\CMS\Core\Utility\HttpUtility::HTTP_STATUS_500);
134 }
135 if (!headers_sent()) {
136 foreach ($headers as $header) {
137 header($header);
138 }
139 }
140 }
141
142 }