MediaWiki  master
MWException.php
Go to the documentation of this file.
1 <?php
26 class MWException extends Exception {
32  public function useOutputPage() {
33  return $this->useMessageCache() &&
34  !empty( $GLOBALS['wgFullyInitialised'] ) &&
35  !empty( $GLOBALS['wgOut'] ) &&
36  !defined( 'MEDIAWIKI_INSTALL' ) &&
37  // Don't send a skinned HTTP 500 page to API clients.
38  !defined( 'MW_API' );
39  }
40 
47  public function isLoggable() {
48  return true;
49  }
50 
56  public function useMessageCache() {
57  foreach ( $this->getTrace() as $frame ) {
58  if ( isset( $frame['class'] ) && $frame['class'] === LocalisationCache::class ) {
59  return false;
60  }
61  }
62  return true;
63  }
64 
74  public function msg( $key, $fallback, ...$params ) {
75  global $wgSitename;
76 
77  // FIXME: Keep logic in sync with MWExceptionRenderer::msg.
78  $res = false;
79  if ( $this->useMessageCache() ) {
80  try {
81  $res = wfMessage( $key, ...$params )->text();
82  } catch ( Exception $e ) {
83  }
84  }
85  if ( $res === false ) {
86  $res = wfMsgReplaceArgs( $fallback, $params );
87  // If an exception happens inside message rendering,
88  // {{SITENAME}} sometimes won't be replaced.
89  $res = strtr( $res, [
90  '{{SITENAME}}' => $wgSitename,
91  ] );
92  }
93  return $res;
94  }
95 
103  public function getHTML() {
105 
106  if ( $wgShowExceptionDetails ) {
107  return '<p>' . nl2br( htmlspecialchars( MWExceptionHandler::getLogMessage( $this ) ) ) .
108  '</p><p>Backtrace:</p><p>' .
109  nl2br( htmlspecialchars( MWExceptionHandler::getRedactedTraceAsString( $this ) ) ) .
110  "</p>\n";
111  } else {
112  $logId = WebRequest::getRequestId();
113  $type = static::class;
114  return Html::errorBox(
115  htmlspecialchars(
116  '[' . $logId . '] ' .
117  gmdate( 'Y-m-d H:i:s' ) . ": " .
118  $this->msg( "internalerror-fatal-exception",
119  "Fatal exception of type $1",
120  $type,
121  $logId,
123  )
124  ) ) .
125  "<!-- Set \$wgShowExceptionDetails = true; " .
126  "at the bottom of LocalSettings.php to show detailed " .
127  "debugging information. -->";
128  }
129  }
130 
138  public function getText() {
140 
141  if ( $wgShowExceptionDetails ) {
142  return MWExceptionHandler::getLogMessage( $this ) .
143  "\nBacktrace:\n" . MWExceptionHandler::getRedactedTraceAsString( $this ) . "\n";
144  } else {
145  return "Set \$wgShowExceptionDetails = true; " .
146  "in LocalSettings.php to show detailed debugging information.\n";
147  }
148  }
149 
155  public function getPageTitle() {
156  return $this->msg( 'internalerror', 'Internal error' );
157  }
158 
162  public function reportHTML() {
163  global $wgOut, $wgSitename;
164  if ( $this->useOutputPage() ) {
165  $wgOut->prepareErrorPage( $this->getPageTitle() );
166  // Manually set the html title, since sometimes
167  // {{SITENAME}} does not get replaced for exceptions
168  // happening inside message rendering.
169  $wgOut->setHTMLTitle(
170  $this->msg(
171  'pagetitle',
172  "$1 - $wgSitename",
173  $this->getPageTitle()
174  )
175  );
176 
177  $wgOut->addHTML( $this->getHTML() );
178 
179  $wgOut->output();
180  } else {
181  self::header( 'Content-Type: text/html; charset=utf-8' );
182  echo "<!DOCTYPE html>\n" .
183  '<html><head>' .
184  // Mimick OutputPage::setPageTitle behaviour
185  '<title>' .
186  htmlspecialchars( $this->msg( 'pagetitle', "$1 - $wgSitename", $this->getPageTitle() ) ) .
187  '</title>' .
188  '<style>body { font-family: sans-serif; margin: 0; padding: 0.5em 2em; }</style>' .
189  "</head><body>\n";
190 
191  echo $this->getHTML();
192 
193  echo "</body></html>\n";
194  }
195  }
196 
201  public function report() {
202  global $wgMimeType;
203 
204  if ( defined( 'MW_API' ) ) {
205  self::header( 'MediaWiki-API-Error: internal_api_error_' . static::class );
206  }
207 
208  if ( self::isCommandLine() ) {
209  $message = $this->getText();
210  $this->writeToCommandLine( $message );
211  } else {
212  self::statusHeader( 500 );
213  self::header( "Content-Type: $wgMimeType; charset=utf-8" );
214 
215  $this->reportHTML();
216  }
217  }
218 
225  private function writeToCommandLine( $message ) {
226  // T17602: STDERR may not be available
227  if ( !defined( 'MW_PHPUNIT_TEST' ) && defined( 'STDERR' ) ) {
228  fwrite( STDERR, $message );
229  } else {
230  echo $message;
231  }
232  }
233 
240  public static function isCommandLine() {
241  return !empty( $GLOBALS['wgCommandLineMode'] );
242  }
243 
249  private static function header( $header ) {
250  if ( !headers_sent() ) {
251  header( $header );
252  }
253  }
254 
255  private static function statusHeader( $code ) {
256  if ( !headers_sent() ) {
257  HttpStatus::header( $code );
258  }
259  }
260 }
$wgMimeType
$wgMimeType
The default Content-Type header.
Definition: DefaultSettings.php:3348
$fallback
$fallback
Definition: MessagesAb.php:11
wfMsgReplaceArgs
wfMsgReplaceArgs( $message, $args)
Replace message parameter keys on the given formatted output.
Definition: GlobalFunctions.php:1233
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1198
$res
$res
Definition: testCompression.php:57
MWException\isLoggable
isLoggable()
Whether to log this exception in the exception debug log.
Definition: MWException.php:47
MWException\useMessageCache
useMessageCache()
Can the extension use the Message class/wfMessage to get i18n-ed messages?
Definition: MWException.php:56
MWException\isCommandLine
static isCommandLine()
Check whether we are in command line mode or not to report the exception in the correct format.
Definition: MWException.php:240
MWExceptionHandler\getRedactedTraceAsString
static getRedactedTraceAsString(Throwable $e)
Generate a string representation of a throwable's stack trace.
Definition: MWExceptionHandler.php:351
MWException
MediaWiki exception.
Definition: MWException.php:26
MWException\getText
getText()
Get the text to display when reporting the error on the command line.
Definition: MWException.php:138
MWExceptionHandler\getURL
static getURL()
If the exception occurred in the course of responding to a request, returns the requested URL.
Definition: MWExceptionHandler.php:442
MWException\getPageTitle
getPageTitle()
Return the title of the page when reporting this error in a HTTP response.
Definition: MWException.php:155
MWException\getHTML
getHTML()
If $wgShowExceptionDetails is true, return a HTML message with a backtrace to the error,...
Definition: MWException.php:103
Html\errorBox
static errorBox( $html, $heading='', $className='')
Return an error box.
Definition: Html.php:739
MWException\report
report()
Output a report about the exception and takes care of formatting.
Definition: MWException.php:201
$header
$header
Definition: updateCredits.php:41
MWException\reportHTML
reportHTML()
Output the exception report using HTML.
Definition: MWException.php:162
$wgSitename
$wgSitename
Name of the site.
Definition: DefaultSettings.php:80
MWException\msg
msg( $key, $fallback,... $params)
Get a message from i18n.
Definition: MWException.php:74
MWException\header
static header( $header)
Send a header, if we haven't already sent them.
Definition: MWException.php:249
HttpStatus\header
static header( $code)
Output an HTTP status code header.
Definition: HttpStatus.php:96
WebRequest\getRequestId
static getRequestId()
Get the unique request ID.
Definition: WebRequest.php:330
$wgShowExceptionDetails
$wgShowExceptionDetails
If set to true, uncaught exceptions will print the exception message and a complete stack trace to ou...
Definition: DefaultSettings.php:6664
MWException\writeToCommandLine
writeToCommandLine( $message)
Write a message to stderr falling back to stdout if stderr unavailable.
Definition: MWException.php:225
$wgOut
$wgOut
Definition: Setup.php:779
MWException\statusHeader
static statusHeader( $code)
Definition: MWException.php:255
MWExceptionHandler\getLogMessage
static getLogMessage(Throwable $e)
Get a message formatting the throwable message and its origin.
Definition: MWExceptionHandler.php:457
$GLOBALS
$GLOBALS['IP']
Definition: ComposerHookHandler.php:6
MWException\useOutputPage
useOutputPage()
Should the exception use $wgOut to output the error?
Definition: MWException.php:32
$type
$type
Definition: testCompression.php:52