MediaWiki REL1_38
MWException.php
Go to the documentation of this file.
1<?php
29class MWException extends Exception {
35 public function useOutputPage() {
36 return $this->useMessageCache() &&
37 !empty( $GLOBALS['wgFullyInitialised'] ) &&
38 !empty( $GLOBALS['wgOut'] ) &&
39 !defined( 'MEDIAWIKI_INSTALL' ) &&
40 // Don't send a skinned HTTP 500 page to API clients.
41 !defined( 'MW_API' );
42 }
43
52 public function isLoggable() {
53 return true;
54 }
55
63 public function useMessageCache() {
64 foreach ( $this->getTrace() as $frame ) {
65 if ( isset( $frame['class'] ) && $frame['class'] === LocalisationCache::class ) {
66 return false;
67 }
68 }
69 return true;
70 }
71
81 public function msg( $key, $fallback, ...$params ) {
82 // FIXME: Keep logic in sync with MWExceptionRenderer::msg.
83 $res = false;
84 if ( $this->useMessageCache() ) {
85 try {
86 $res = wfMessage( $key, ...$params )->text();
87 } catch ( Exception $e ) {
88 }
89 }
90 if ( $res === false ) {
91 // Fallback to static message text and generic sitename.
92 // Avoid live config as this must work before Setup/MediaWikiServices finish.
93 $res = wfMsgReplaceArgs( $fallback, $params );
94 $res = strtr( $res, [
95 '{{SITENAME}}' => 'MediaWiki',
96 ] );
97 }
98 return $res;
99 }
100
110 public function getHTML() {
112
114 return '<p>' . nl2br( htmlspecialchars( MWExceptionHandler::getLogMessage( $this ) ) ) .
115 '</p><p>Backtrace:</p><p>' .
116 nl2br( htmlspecialchars( MWExceptionHandler::getRedactedTraceAsString( $this ) ) ) .
117 "</p>\n";
118 } else {
119 $logId = WebRequest::getRequestId();
120 $type = static::class;
121 return Html::errorBox(
122 htmlspecialchars(
123 '[' . $logId . '] ' .
124 gmdate( 'Y-m-d H:i:s' ) . ": " .
125 $this->msg( "internalerror-fatal-exception",
126 "Fatal exception of type $1",
127 $type,
128 $logId,
129 MWExceptionHandler::getURL()
130 )
131 ) ) .
132 "<!-- Set \$wgShowExceptionDetails = true; " .
133 "at the bottom of LocalSettings.php to show detailed " .
134 "debugging information. -->";
135 }
136 }
137
147 public function getText() {
149
151 return MWExceptionHandler::getLogMessage( $this ) .
152 "\nBacktrace:\n" . MWExceptionHandler::getRedactedTraceAsString( $this ) . "\n";
153 } else {
154 return "Set \$wgShowExceptionDetails = true; " .
155 "in LocalSettings.php to show detailed debugging information.\n";
156 }
157 }
158
166 public function getPageTitle() {
167 return $this->msg( 'internalerror', 'Internal error' );
168 }
169
174 public function reportHTML() {
175 global $wgOut;
176 if ( $this->useOutputPage() ) {
177 $wgOut->prepareErrorPage( $this->getPageTitle() );
178 // Manually set the html title, since sometimes
179 // {{SITENAME}} does not get replaced for exceptions
180 // happening inside message rendering.
181 $wgOut->setHTMLTitle(
182 $this->msg( 'pagetitle', '$1 - MediaWiki', $this->getPageTitle() )
183 );
184
185 $wgOut->addHTML( $this->getHTML() );
186 // Content-Type is set by OutputPage::output
187 $wgOut->output();
188 } else {
189 self::header( 'Content-Type: text/html; charset=UTF-8' );
190 echo "<!DOCTYPE html>\n" .
191 '<html><head>' .
192 // Mimic OutputPage::setPageTitle behaviour
193 '<title>' .
194 htmlspecialchars( $this->msg( 'pagetitle', '$1 - MediaWiki', $this->getPageTitle() ) ) .
195 '</title>' .
196 '<style>body { font-family: sans-serif; margin: 0; padding: 0.5em 2em; }</style>' .
197 "</head><body>\n";
198
199 echo $this->getHTML();
200
201 echo "</body></html>\n";
202 }
203 }
204
211 public function report() {
212 if ( defined( 'MW_API' ) ) {
213 self::header( 'MediaWiki-API-Error: internal_api_error_' . static::class );
214 }
215
216 if ( self::isCommandLine() ) {
217 $message = $this->getText();
218 $this->writeToCommandLine( $message );
219 } else {
220 self::statusHeader( 500 );
221 $this->reportHTML();
222 }
223 }
224
231 private function writeToCommandLine( $message ) {
232 // T17602: STDERR may not be available
233 if ( !defined( 'MW_PHPUNIT_TEST' ) && defined( 'STDERR' ) ) {
234 fwrite( STDERR, $message );
235 } else {
236 echo $message;
237 }
238 }
239
246 public static function isCommandLine() {
247 return !empty( $GLOBALS['wgCommandLineMode'] );
248 }
249
255 private static function header( $header ) {
256 if ( !headers_sent() ) {
257 header( $header );
258 }
259 }
260
261 private static function statusHeader( $code ) {
262 if ( !headers_sent() ) {
263 HttpStatus::header( $code );
264 }
265 }
266}
$wgShowExceptionDetails
If set to true, uncaught exceptions will print the exception message and a complete stack trace to ou...
wfMsgReplaceArgs( $message, $args)
Replace message parameter keys on the given formatted output.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
$fallback
if(!defined( 'MW_NO_SESSION') &&! $wgCommandLineMode) $wgOut
Definition Setup.php:927
MediaWiki exception.
writeToCommandLine( $message)
Write a message to stderr falling back to stdout if stderr unavailable.
static statusHeader( $code)
isLoggable()
Whether to log this exception in the exception debug log.
useMessageCache()
Can the extension use the Message class/wfMessage to get i18n-ed messages?
msg( $key, $fallback,... $params)
Get a message from i18n.
static header( $header)
Send a header, if we haven't already sent them.
getHTML()
If $wgShowExceptionDetails is true, return a HTML message with a backtrace to the error,...
static isCommandLine()
Check whether we are in command line mode or not to report the exception in the correct format.
useOutputPage()
Should the exception use $wgOut to output the error?
report()
Output a report about the exception and takes care of formatting.
getPageTitle()
Return the title of the page when reporting this error in a HTTP response.
reportHTML()
Output the exception report using HTML.
getText()
Get the text to display when reporting the error on the command line.
$header