MediaWiki REL1_41
MWException.php
Go to the documentation of this file.
1<?php
23
33class MWException extends Exception {
39 private function useOutputPage() {
40 // NOTE: keep in sync with MWExceptionRenderer::useOutputPage
41 return $this->useMessageCache() &&
42 !empty( $GLOBALS['wgFullyInitialised'] ) &&
43 !empty( $GLOBALS['wgOut'] ) &&
44 !defined( 'MEDIAWIKI_INSTALL' ) &&
45 // Don't send a skinned HTTP 500 page to API clients.
46 !defined( 'MW_API' );
47 }
48
57 public function isLoggable() {
58 return true;
59 }
60
68 public function useMessageCache() {
69 foreach ( $this->getTrace() as $frame ) {
70 if ( isset( $frame['class'] ) && $frame['class'] === LocalisationCache::class ) {
71 return false;
72 }
73 }
74 return true;
75 }
76
86 public function msg( $key, $fallback, ...$params ) {
87 // NOTE: Keep logic in sync with MWExceptionRenderer::msg.
88 $res = false;
89 if ( $this->useMessageCache() ) {
90 try {
91 $res = wfMessage( $key, ...$params )->text();
92 } catch ( Exception $e ) {
93 }
94 }
95 if ( $res === false ) {
96 // Fallback to static message text and generic sitename.
97 // Avoid live config as this must work before Setup/MediaWikiServices finish.
98 $res = wfMsgReplaceArgs( $fallback, $params );
99 $res = strtr( $res, [
100 '{{SITENAME}}' => 'MediaWiki',
101 ] );
102 }
103 return $res;
104 }
105
114 public function getHTML() {
115 if ( MWExceptionRenderer::shouldShowExceptionDetails() ) {
116 return '<p>' . nl2br( htmlspecialchars( MWExceptionHandler::getLogMessage( $this ) ) ) .
117 '</p><p>Backtrace:</p><p>' .
118 nl2br( htmlspecialchars( MWExceptionHandler::getRedactedTraceAsString( $this ) ) ) .
119 "</p>\n";
120 } else {
121 $logId = WebRequest::getRequestId();
122 $type = static::class;
123 return Html::errorBox(
124 htmlspecialchars(
125 '[' . $logId . '] ' .
126 gmdate( 'Y-m-d H:i:s' ) . ": " .
127 $this->msg( "internalerror-fatal-exception",
128 "Fatal exception of type $1",
129 $type,
130 $logId,
131 MWExceptionHandler::getURL()
132 )
133 ) ) .
134 "<!-- Set \$wgShowExceptionDetails = true; " .
135 "at the bottom of LocalSettings.php to show detailed " .
136 "debugging information. -->";
137 }
138 }
139
147 public function getText() {
148 if ( MWExceptionRenderer::shouldShowExceptionDetails() ) {
149 return MWExceptionHandler::getLogMessage( $this ) .
150 "\nBacktrace:\n" . MWExceptionHandler::getRedactedTraceAsString( $this ) . "\n";
151 } else {
152 return "Set \$wgShowExceptionDetails = true; " .
153 "in LocalSettings.php to show detailed debugging information.\n";
154 }
155 }
156
164 public function getPageTitle() {
165 return $this->msg( 'internalerror', 'Internal error' );
166 }
167
172 public function reportHTML() {
173 global $wgOut;
174 if ( $this->useOutputPage() ) {
175 $wgOut->prepareErrorPage();
176 $wgOut->setPageTitle( $this->getPageTitle() );
177 // Manually set the html title, since sometimes
178 // {{SITENAME}} does not get replaced for exceptions
179 // happening inside message rendering.
180 $wgOut->setHTMLTitle(
181 $this->msg( 'pagetitle', '$1 - MediaWiki', $this->getPageTitle() )
182 );
183
184 $wgOut->addHTML( $this->getHTML() );
185 // Content-Type is set by OutputPage::output
186 $wgOut->output();
187 } else {
188 self::header( 'Content-Type: text/html; charset=UTF-8' );
189 echo "<!DOCTYPE html>\n" .
190 '<html><head>' .
191 // Mimic OutputPage::setPageTitle behaviour
192 '<title>' .
193 htmlspecialchars( $this->msg( 'pagetitle', '$1 - MediaWiki', $this->getPageTitle() ) ) .
194 '</title>' .
195 '<style>body { font-family: sans-serif; margin: 0; padding: 0.5em 2em; }</style>' .
196 "</head><body>\n";
197
198 echo $this->getHTML();
199
200 echo "</body></html>\n";
201 }
202 }
203
210 public function report() {
211 if ( defined( 'MW_API' ) ) {
212 self::header( 'MediaWiki-API-Error: internal_api_error_' . static::class );
213 }
214
215 if ( self::isCommandLine() ) {
216 $message = $this->getText();
217 $this->writeToCommandLine( $message );
218 } else {
219 self::statusHeader( 500 );
220 $this->reportHTML();
221 }
222 }
223
230 private function writeToCommandLine( $message ) {
231 // T17602: STDERR may not be available
232 if ( !defined( 'MW_PHPUNIT_TEST' ) && defined( 'STDERR' ) ) {
233 fwrite( STDERR, $message );
234 } else {
235 echo $message;
236 }
237 }
238
245 public static function isCommandLine() {
246 return !empty( $GLOBALS['wgCommandLineMode'] );
247 }
248
254 private static function header( $header ) {
255 if ( !headers_sent() ) {
256 header( $header );
257 }
258 }
259
260 private static function statusHeader( $code ) {
261 if ( !headers_sent() ) {
262 HttpStatus::header( $code );
263 }
264 }
265}
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
Definition MessagesAb.php:8
if(!defined( 'MW_NO_SESSION') &&! $wgCommandLineMode $wgOut
Definition Setup.php:535
static header( $code)
Output an HTTP status code header.
MediaWiki exception.
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.
getHTML()
Format an HTML message for the current exception object.
static isCommandLine()
Check whether we are in command line mode or not to report the exception in the correct format.
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()
Format plain text message for the current exception object.
This class is a collection of static functions that serve two purposes:
Definition Html.php:57
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
$header