00001 <?php
00010 class MWException extends Exception {
00015 function useOutputPage() {
00016 return $this->useMessageCache() &&
00017 !empty( $GLOBALS['wgFullyInitialised'] ) &&
00018 ( !empty( $GLOBALS['wgArticle'] ) || ( !empty( $GLOBALS['wgOut'] ) && !$GLOBALS['wgOut']->isArticle() ) ) &&
00019 !empty( $GLOBALS['wgTitle'] );
00020 }
00021
00026 function useMessageCache() {
00027 global $wgLang;
00028 foreach ( $this->getTrace() as $frame ) {
00029 if ( isset( $frame['class'] ) && $frame['class'] === 'LocalisationCache' ) {
00030 return false;
00031 }
00032 }
00033 return is_object( $wgLang );
00034 }
00035
00043 function runHooks( $name, $args = array() ) {
00044 global $wgExceptionHooks;
00045 if( !isset( $wgExceptionHooks ) || !is_array( $wgExceptionHooks ) )
00046 return;
00047 if( !array_key_exists( $name, $wgExceptionHooks ) || !is_array( $wgExceptionHooks[ $name ] ) )
00048 return;
00049 $hooks = $wgExceptionHooks[ $name ];
00050 $callargs = array_merge( array( $this ), $args );
00051
00052 foreach( $hooks as $hook ) {
00053 if( is_string( $hook ) || ( is_array( $hook ) && count( $hook ) >= 2 && is_string( $hook[0] ) ) ) {
00054 $result = call_user_func_array( $hook, $callargs );
00055 } else {
00056 $result = null;
00057 }
00058 if( is_string( $result ) )
00059 return $result;
00060 }
00061 }
00062
00072 function msg( $key, $fallback ) {
00073 $args = array_slice( func_get_args(), 2 );
00074 if ( $this->useMessageCache() ) {
00075 return wfMsgReal( $key, $args );
00076 } else {
00077 return wfMsgReplaceArgs( $fallback, $args );
00078 }
00079 }
00080
00088 function getHTML() {
00089 global $wgShowExceptionDetails;
00090 if( $wgShowExceptionDetails ) {
00091 return '<p>' . nl2br( htmlspecialchars( $this->getMessage() ) ) .
00092 '</p><p>Backtrace:</p><p>' . nl2br( htmlspecialchars( $this->getTraceAsString() ) ) .
00093 "</p>\n";
00094 } else {
00095 return "<p>Set <b><tt>\$wgShowExceptionDetails = true;</tt></b> " .
00096 "at the bottom of LocalSettings.php to show detailed " .
00097 "debugging information.</p>";
00098 }
00099 }
00100
00105 function getText() {
00106 global $wgShowExceptionDetails;
00107 if( $wgShowExceptionDetails ) {
00108 return $this->getMessage() .
00109 "\nBacktrace:\n" . $this->getTraceAsString() . "\n";
00110 } else {
00111 return "Set \$wgShowExceptionDetails = true; " .
00112 "in LocalSettings.php to show detailed debugging information.\n";
00113 }
00114 }
00115
00116
00117 function getPageTitle() {
00118 if ( $this->useMessageCache() ) {
00119 return wfMsg( 'internalerror' );
00120 } else {
00121 global $wgSitename;
00122 return "$wgSitename error";
00123 }
00124 }
00125
00132 function getLogMessage() {
00133 global $wgRequest;
00134 $file = $this->getFile();
00135 $line = $this->getLine();
00136 $message = $this->getMessage();
00137 if ( isset( $wgRequest ) ) {
00138 $url = $wgRequest->getRequestURL();
00139 if ( !$url ) {
00140 $url = '[no URL]';
00141 }
00142 } else {
00143 $url = '[no req]';
00144 }
00145
00146 return "$url Exception from line $line of $file: $message";
00147 }
00148
00150 function reportHTML() {
00151 global $wgOut;
00152 if ( $this->useOutputPage() ) {
00153 $wgOut->setPageTitle( $this->getPageTitle() );
00154 $wgOut->setRobotPolicy( "noindex,nofollow" );
00155 $wgOut->setArticleRelated( false );
00156 $wgOut->enableClientCache( false );
00157 $wgOut->redirect( '' );
00158 $wgOut->clearHTML();
00159 if( $hookResult = $this->runHooks( get_class( $this ) ) ) {
00160 $wgOut->addHTML( $hookResult );
00161 } else {
00162 $wgOut->addHTML( $this->getHTML() );
00163 }
00164 $wgOut->output();
00165 } else {
00166 if( $hookResult = $this->runHooks( get_class( $this ) . "Raw" ) ) {
00167 die( $hookResult );
00168 }
00169 if ( defined( 'MEDIAWIKI_INSTALL' ) || $this->htmlBodyOnly() ) {
00170 echo $this->getHTML();
00171 } else {
00172 echo $this->htmlHeader();
00173 echo $this->getHTML();
00174 echo $this->htmlFooter();
00175 }
00176 }
00177 }
00178
00183 function report() {
00184 $log = $this->getLogMessage();
00185 if ( $log ) {
00186 wfDebugLog( 'exception', $log );
00187 }
00188 if ( self::isCommandLine() ) {
00189 wfPrintError( $this->getText() );
00190 } else {
00191 $this->reportHTML();
00192 }
00193 }
00194
00199 function htmlHeader() {
00200 global $wgLogo, $wgSitename, $wgOutputEncoding;
00201
00202 if ( !headers_sent() ) {
00203 header( 'HTTP/1.0 500 Internal Server Error' );
00204 header( 'Content-type: text/html; charset='.$wgOutputEncoding );
00205
00206 header( 'Cache-control: none' );
00207 header( 'Pragma: nocache' );
00208 }
00209 $title = $this->getPageTitle();
00210 return "<html>
00211 <head>
00212 <title>$title</title>
00213 </head>
00214 <body>
00215 <h1><img src='$wgLogo' style='float:left;margin-right:1em' alt=''/>$title</h1>
00216 ";
00217 }
00218
00222 function htmlFooter() {
00223 return "</body></html>";
00224 }
00225
00229 function htmlBodyOnly() {
00230 return false;
00231 }
00232
00233 static function isCommandLine() {
00234 return !empty( $GLOBALS['wgCommandLineMode'] ) && !defined( 'MEDIAWIKI_INSTALL' );
00235 }
00236 }
00237
00243 class FatalError extends MWException {
00244 function getHTML() {
00245 return $this->getMessage();
00246 }
00247
00248 function getText() {
00249 return $this->getMessage();
00250 }
00251 }
00252
00256 class ErrorPageError extends MWException {
00257 public $title, $msg;
00258
00262 function __construct( $title, $msg ) {
00263 $this->title = $title;
00264 $this->msg = $msg;
00265 parent::__construct( wfMsg( $msg ) );
00266 }
00267
00268 function report() {
00269 global $wgOut;
00270 $wgOut->showErrorPage( $this->title, $this->msg );
00271 $wgOut->output();
00272 }
00273 }
00274
00278 function wfInstallExceptionHandler() {
00279 set_exception_handler( 'wfExceptionHandler' );
00280 }
00281
00285 function wfReportException( Exception $e ) {
00286 $cmdLine = MWException::isCommandLine();
00287 if ( $e instanceof MWException ) {
00288 try {
00289 $e->report();
00290 } catch ( Exception $e2 ) {
00291
00292
00293
00294 $message = "MediaWiki internal error.\n\n";
00295 if ( $GLOBALS['wgShowExceptionDetails'] )
00296 $message .= "Original exception: " . $e->__toString();
00297 $message .= "\n\nException caught inside exception handler";
00298 if ( $GLOBALS['wgShowExceptionDetails'] )
00299 $message .= ": " . $e2->__toString();
00300 $message .= "\n";
00301 if ( $cmdLine ) {
00302 wfPrintError( $message );
00303 } else {
00304 echo nl2br( htmlspecialchars( $message ) ). "\n";
00305 }
00306 }
00307 } else {
00308 $message = "Unexpected non-MediaWiki exception encountered, of type \"" . get_class( $e ) . "\"\n" .
00309 $e->__toString() . "\n";
00310 if ( $GLOBALS['wgShowExceptionDetails'] ) {
00311 $message .= "\n" . $e->getTraceAsString() ."\n";
00312 }
00313 if ( $cmdLine ) {
00314 wfPrintError( $message );
00315 } else {
00316 echo nl2br( htmlspecialchars( $message ) ). "\n";
00317 }
00318 }
00319 }
00320
00325 function wfPrintError( $message ) {
00326 #NOTE: STDERR may not be available, especially if php-cgi is used from the command line (bug #15602).
00327 # Try to produce meaningful output anyway. Using echo may corrupt output to STDOUT though.
00328 if ( defined( 'STDERR' ) ) {
00329 fwrite( STDERR, $message );
00330 } else {
00331 echo( $message );
00332 }
00333 }
00334
00346 function wfExceptionHandler( $e ) {
00347 global $wgFullyInitialised;
00348 wfReportException( $e );
00349
00350
00351 if ( $wgFullyInitialised ) {
00352 try {
00353 wfLogProfilingData();
00354 } catch ( Exception $e ) {}
00355 }
00356
00357
00358 exit( 1 );
00359 }