00001 <?php
00010 class MWException extends Exception {
00011
00016 function useOutputPage() {
00017 return !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 return is_object( $wgLang );
00029 }
00030
00038 function runHooks( $name, $args = array() ) {
00039 global $wgExceptionHooks;
00040 if( !isset( $wgExceptionHooks ) || !is_array( $wgExceptionHooks ) )
00041 return;
00042 if( !array_key_exists( $name, $wgExceptionHooks ) || !is_array( $wgExceptionHooks[ $name ] ) )
00043 return;
00044 $hooks = $wgExceptionHooks[ $name ];
00045 $callargs = array_merge( array( $this ), $args );
00046
00047 foreach( $hooks as $hook ) {
00048 if( is_string( $hook ) || ( is_array( $hook ) && count( $hook ) >= 2 && is_string( $hook[0] ) ) ) {
00049 $result = call_user_func_array( $hook, $callargs );
00050 } else {
00051 $result = null;
00052 }
00053 if( is_string( $result ) )
00054 return $result;
00055 }
00056 }
00057
00067 function msg( $key, $fallback ) {
00068 $args = array_slice( func_get_args(), 2 );
00069 if ( $this->useMessageCache() ) {
00070 return wfMsgReal( $key, $args );
00071 } else {
00072 return wfMsgReplaceArgs( $fallback, $args );
00073 }
00074 }
00075
00083 function getHTML() {
00084 global $wgShowExceptionDetails;
00085 if( $wgShowExceptionDetails ) {
00086 return '<p>' . nl2br( htmlspecialchars( $this->getMessage() ) ) .
00087 '</p><p>Backtrace:</p><p>' . nl2br( htmlspecialchars( $this->getTraceAsString() ) ) .
00088 "</p>\n";
00089 } else {
00090 return "<p>Set <b><tt>\$wgShowExceptionDetails = true;</tt></b> " .
00091 "at the bottom of LocalSettings.php to show detailed " .
00092 "debugging information.</p>";
00093 }
00094 }
00095
00100 function getText() {
00101 global $wgShowExceptionDetails;
00102 if( $wgShowExceptionDetails ) {
00103 return $this->getMessage() .
00104 "\nBacktrace:\n" . $this->getTraceAsString() . "\n";
00105 } else {
00106 return "Set \$wgShowExceptionDetails = true; " .
00107 "in LocalSettings.php to show detailed debugging information.\n";
00108 }
00109 }
00110
00111
00112 function getPageTitle() {
00113 if ( $this->useMessageCache() ) {
00114 return wfMsg( 'internalerror' );
00115 } else {
00116 global $wgSitename;
00117 return "$wgSitename error";
00118 }
00119 }
00120
00127 function getLogMessage() {
00128 global $wgRequest;
00129 $file = $this->getFile();
00130 $line = $this->getLine();
00131 $message = $this->getMessage();
00132 if ( isset( $wgRequest ) ) {
00133 $url = $wgRequest->getRequestURL();
00134 if ( !$url ) {
00135 $url = '[no URL]';
00136 }
00137 } else {
00138 $url = '[no req]';
00139 }
00140
00141 return "$url Exception from line $line of $file: $message";
00142 }
00143
00145 function reportHTML() {
00146 global $wgOut;
00147 if ( $this->useOutputPage() ) {
00148 $wgOut->setPageTitle( $this->getPageTitle() );
00149 $wgOut->setRobotPolicy( "noindex,nofollow" );
00150 $wgOut->setArticleRelated( false );
00151 $wgOut->enableClientCache( false );
00152 $wgOut->redirect( '' );
00153 $wgOut->clearHTML();
00154 if( $hookResult = $this->runHooks( get_class( $this ) ) ) {
00155 $wgOut->addHTML( $hookResult );
00156 } else {
00157 $wgOut->addHTML( $this->getHTML() );
00158 }
00159 $wgOut->output();
00160 } else {
00161 if( $hookResult = $this->runHooks( get_class( $this ) . "Raw" ) ) {
00162 die( $hookResult );
00163 }
00164 if ( defined( 'MEDIAWIKI_INSTALL' ) || $this->htmlBodyOnly() ) {
00165 echo $this->getHTML();
00166 } else {
00167 echo $this->htmlHeader();
00168 echo $this->getHTML();
00169 echo $this->htmlFooter();
00170 }
00171 }
00172 }
00173
00178 function report() {
00179 $log = $this->getLogMessage();
00180 if ( $log ) {
00181 wfDebugLog( 'exception', $log );
00182 }
00183 if ( self::isCommandLine() ) {
00184 wfPrintError( $this->getText() );
00185 } else {
00186 $this->reportHTML();
00187 }
00188 }
00189
00194 function htmlHeader() {
00195 global $wgLogo, $wgSitename, $wgOutputEncoding;
00196
00197 if ( !headers_sent() ) {
00198 header( 'HTTP/1.0 500 Internal Server Error' );
00199 header( 'Content-type: text/html; charset='.$wgOutputEncoding );
00200
00201 header( 'Cache-control: none' );
00202 header( 'Pragma: nocache' );
00203 }
00204 $title = $this->getPageTitle();
00205 echo "<html>
00206 <head>
00207 <title>$title</title>
00208 </head>
00209 <body>
00210 <h1><img src='$wgLogo' style='float:left;margin-right:1em' alt=''/>$title</h1>
00211 ";
00212 }
00213
00217 function htmlFooter() {
00218 echo "</body></html>";
00219 }
00220
00224 function htmlBodyOnly() {
00225 return false;
00226 }
00227
00228 static function isCommandLine() {
00229 return !empty( $GLOBALS['wgCommandLineMode'] ) && !defined( 'MEDIAWIKI_INSTALL' );
00230 }
00231 }
00232
00238 class FatalError extends MWException {
00239 function getHTML() {
00240 return $this->getMessage();
00241 }
00242
00243 function getText() {
00244 return $this->getMessage();
00245 }
00246 }
00247
00251 class ErrorPageError extends MWException {
00252 public $title, $msg;
00253
00257 function __construct( $title, $msg ) {
00258 $this->title = $title;
00259 $this->msg = $msg;
00260 parent::__construct( wfMsg( $msg ) );
00261 }
00262
00263 function report() {
00264 global $wgOut;
00265 $wgOut->showErrorPage( $this->title, $this->msg );
00266 $wgOut->output();
00267 }
00268 }
00269
00273 function wfInstallExceptionHandler() {
00274 set_exception_handler( 'wfExceptionHandler' );
00275 }
00276
00280 function wfReportException( Exception $e ) {
00281 $cmdLine = MWException::isCommandLine();
00282 if ( $e instanceof MWException ) {
00283 try {
00284 $e->report();
00285 } catch ( Exception $e2 ) {
00286
00287
00288
00289 $message = "MediaWiki internal error.\n\n";
00290 if ( $GLOBALS['wgShowExceptionDetails'] )
00291 $message .= "Original exception: " . $e->__toString();
00292 $message .= "\n\nException caught inside exception handler";
00293 if ( $GLOBALS['wgShowExceptionDetails'] )
00294 $message .= ": " . $e2->__toString();
00295 $message .= "\n";
00296 if ( $cmdLine ) {
00297 wfPrintError( $message );
00298 } else {
00299 echo nl2br( htmlspecialchars( $message ) ). "\n";
00300 }
00301 }
00302 } else {
00303 $message = "Unexpected non-MediaWiki exception encountered, of type \"" . get_class( $e ) . "\"\n" .
00304 $e->__toString() . "\n";
00305 if ( $GLOBALS['wgShowExceptionDetails'] ) {
00306 $message .= "\n" . $e->getTraceAsString() ."\n";
00307 }
00308 if ( $cmdLine ) {
00309 wfPrintError( $message );
00310 } else {
00311 echo nl2br( htmlspecialchars( $message ) ). "\n";
00312 }
00313 }
00314 }
00315
00320 function wfPrintError( $message ) {
00321 #NOTE: STDERR may not be available, especially if php-cgi is used from the command line (bug #15602).
00322 # Try to produce meaningful output anyway. Using echo may corrupt output to STDOUT though.
00323 if ( defined( 'STDERR' ) ) {
00324 fwrite( STDERR, $message );
00325 }
00326 else {
00327 echo( $message );
00328 }
00329 }
00330
00342 function wfExceptionHandler( $e ) {
00343 global $wgFullyInitialised;
00344 wfReportException( $e );
00345
00346
00347 if ( $wgFullyInitialised ) {
00348 try {
00349 wfLogProfilingData();
00350 } catch ( Exception $e ) {}
00351 }
00352
00353
00354 exit( 1 );
00355 }