MediaWiki  master
MWException.php
Go to the documentation of this file.
1 <?php
29 class 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  global $wgSitename;
83 
84  // FIXME: Keep logic in sync with MWExceptionRenderer::msg.
85  $res = false;
86  if ( $this->useMessageCache() ) {
87  try {
88  $res = wfMessage( $key, ...$params )->text();
89  } catch ( Exception $e ) {
90  }
91  }
92  if ( $res === false ) {
93  $res = wfMsgReplaceArgs( $fallback, $params );
94  // If an exception happens inside message rendering,
95  // {{SITENAME}} sometimes won't be replaced.
96  $res = strtr( $res, [
97  '{{SITENAME}}' => $wgSitename,
98  ] );
99  }
100  return $res;
101  }
102 
112  public function getHTML() {
114 
115  if ( $wgShowExceptionDetails ) {
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,
132  )
133  ) ) .
134  "<!-- Set \$wgShowExceptionDetails = true; " .
135  "at the bottom of LocalSettings.php to show detailed " .
136  "debugging information. -->";
137  }
138  }
139 
149  public function getText() {
151 
152  if ( $wgShowExceptionDetails ) {
153  return MWExceptionHandler::getLogMessage( $this ) .
154  "\nBacktrace:\n" . MWExceptionHandler::getRedactedTraceAsString( $this ) . "\n";
155  } else {
156  return "Set \$wgShowExceptionDetails = true; " .
157  "in LocalSettings.php to show detailed debugging information.\n";
158  }
159  }
160 
168  public function getPageTitle() {
169  return $this->msg( 'internalerror', 'Internal error' );
170  }
171 
176  public function reportHTML() {
177  global $wgOut, $wgSitename;
178  if ( $this->useOutputPage() ) {
179  $wgOut->prepareErrorPage( $this->getPageTitle() );
180  // Manually set the html title, since sometimes
181  // {{SITENAME}} does not get replaced for exceptions
182  // happening inside message rendering.
183  $wgOut->setHTMLTitle(
184  $this->msg(
185  'pagetitle',
186  "$1 - $wgSitename",
187  $this->getPageTitle()
188  )
189  );
190 
191  $wgOut->addHTML( $this->getHTML() );
192 
193  $wgOut->output();
194  } else {
195  self::header( 'Content-Type: text/html; charset=utf-8' );
196  echo "<!DOCTYPE html>\n" .
197  '<html><head>' .
198  // Mimick OutputPage::setPageTitle behaviour
199  '<title>' .
200  htmlspecialchars( $this->msg( 'pagetitle', "$1 - $wgSitename", $this->getPageTitle() ) ) .
201  '</title>' .
202  '<style>body { font-family: sans-serif; margin: 0; padding: 0.5em 2em; }</style>' .
203  "</head><body>\n";
204 
205  echo $this->getHTML();
206 
207  echo "</body></html>\n";
208  }
209  }
210 
217  public function report() {
218  global $wgMimeType;
219 
220  if ( defined( 'MW_API' ) ) {
221  self::header( 'MediaWiki-API-Error: internal_api_error_' . static::class );
222  }
223 
224  if ( self::isCommandLine() ) {
225  $message = $this->getText();
226  $this->writeToCommandLine( $message );
227  } else {
228  self::statusHeader( 500 );
229  self::header( "Content-Type: $wgMimeType; charset=utf-8" );
230 
231  $this->reportHTML();
232  }
233  }
234 
241  private function writeToCommandLine( $message ) {
242  // T17602: STDERR may not be available
243  if ( !defined( 'MW_PHPUNIT_TEST' ) && defined( 'STDERR' ) ) {
244  fwrite( STDERR, $message );
245  } else {
246  echo $message;
247  }
248  }
249 
256  public static function isCommandLine() {
257  return !empty( $GLOBALS['wgCommandLineMode'] );
258  }
259 
265  private static function header( $header ) {
266  if ( !headers_sent() ) {
267  header( $header );
268  }
269  }
270 
271  private static function statusHeader( $code ) {
272  if ( !headers_sent() ) {
273  HttpStatus::header( $code );
274  }
275  }
276 }
$wgMimeType
$wgMimeType
The default Content-Type header.
Definition: DefaultSettings.php:3386
$fallback
$fallback
Definition: MessagesAb.php:11
wfMsgReplaceArgs
wfMsgReplaceArgs( $message, $args)
Replace message parameter keys on the given formatted output.
Definition: GlobalFunctions.php:1254
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1219
$res
$res
Definition: testCompression.php:57
MWException\isLoggable
isLoggable()
Whether to log this exception in the exception debug log.
Definition: MWException.php:52
MWException\useMessageCache
useMessageCache()
Can the extension use the Message class/wfMessage to get i18n-ed messages?
Definition: MWException.php:63
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:256
MWExceptionHandler\getRedactedTraceAsString
static getRedactedTraceAsString(Throwable $e)
Generate a string representation of a throwable's stack trace.
Definition: MWExceptionHandler.php:364
MWException
MediaWiki exception.
Definition: MWException.php:29
MWException\getText
getText()
Get the text to display when reporting the error on the command line.
Definition: MWException.php:149
MWExceptionHandler\getURL
static getURL()
If the exception occurred in the course of responding to a request, returns the requested URL.
Definition: MWExceptionHandler.php:455
MWException\getPageTitle
getPageTitle()
Return the title of the page when reporting this error in a HTTP response.
Definition: MWException.php:168
MWException\getHTML
getHTML()
If $wgShowExceptionDetails is true, return a HTML message with a backtrace to the error,...
Definition: MWException.php:112
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:217
$header
$header
Definition: updateCredits.php:41
MWException\reportHTML
reportHTML()
Output the exception report using HTML.
Definition: MWException.php:176
$wgSitename
$wgSitename
Name of the site.
Definition: DefaultSettings.php:80
MWException\msg
msg( $key, $fallback,... $params)
Get a message from i18n.
Definition: MWException.php:81
MWException\header
static header( $header)
Send a header, if we haven't already sent them.
Definition: MWException.php:265
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:327
$wgShowExceptionDetails
$wgShowExceptionDetails
If set to true, uncaught exceptions will print the exception message and a complete stack trace to ou...
Definition: DefaultSettings.php:6741
MWException\writeToCommandLine
writeToCommandLine( $message)
Write a message to stderr falling back to stdout if stderr unavailable.
Definition: MWException.php:241
$wgOut
$wgOut
Definition: Setup.php:781
MWException\statusHeader
static statusHeader( $code)
Definition: MWException.php:271
MWExceptionHandler\getLogMessage
static getLogMessage(Throwable $e)
Get a message formatting the throwable message and its origin.
Definition: MWExceptionHandler.php:474
$GLOBALS
$GLOBALS['IP']
Definition: ComposerHookHandler.php:6
MWException\useOutputPage
useOutputPage()
Should the exception use $wgOut to output the error?
Definition: MWException.php:35
$type
$type
Definition: testCompression.php:52