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