MediaWiki
REL1_24
|
00001 <?php 00026 class MWException extends Exception { 00032 public function useOutputPage() { 00033 return $this->useMessageCache() && 00034 !empty( $GLOBALS['wgFullyInitialised'] ) && 00035 !empty( $GLOBALS['wgOut'] ) && 00036 !defined( 'MEDIAWIKI_INSTALL' ); 00037 } 00038 00045 public function isLoggable() { 00046 return true; 00047 } 00048 00054 public function useMessageCache() { 00055 global $wgLang; 00056 00057 foreach ( $this->getTrace() as $frame ) { 00058 if ( isset( $frame['class'] ) && $frame['class'] === 'LocalisationCache' ) { 00059 return false; 00060 } 00061 } 00062 00063 return $wgLang instanceof Language; 00064 } 00065 00073 public function runHooks( $name, $args = array() ) { 00074 global $wgExceptionHooks; 00075 00076 if ( !isset( $wgExceptionHooks ) || !is_array( $wgExceptionHooks ) ) { 00077 return null; // Just silently ignore 00078 } 00079 00080 if ( !array_key_exists( $name, $wgExceptionHooks ) || 00081 !is_array( $wgExceptionHooks[$name] ) 00082 ) { 00083 return null; 00084 } 00085 00086 $hooks = $wgExceptionHooks[$name]; 00087 $callargs = array_merge( array( $this ), $args ); 00088 00089 foreach ( $hooks as $hook ) { 00090 if ( 00091 is_string( $hook ) || 00092 ( is_array( $hook ) && count( $hook ) >= 2 && is_string( $hook[0] ) ) 00093 ) { 00094 // 'function' or array( 'class', hook' ) 00095 $result = call_user_func_array( $hook, $callargs ); 00096 } else { 00097 $result = null; 00098 } 00099 00100 if ( is_string( $result ) ) { 00101 return $result; 00102 } 00103 } 00104 return null; 00105 } 00106 00116 public function msg( $key, $fallback /*[, params...] */ ) { 00117 $args = array_slice( func_get_args(), 2 ); 00118 00119 if ( $this->useMessageCache() ) { 00120 return wfMessage( $key, $args )->text(); 00121 } else { 00122 return wfMsgReplaceArgs( $fallback, $args ); 00123 } 00124 } 00125 00133 public function getHTML() { 00134 global $wgShowExceptionDetails; 00135 00136 if ( $wgShowExceptionDetails ) { 00137 return '<p>' . nl2br( htmlspecialchars( MWExceptionHandler::getLogMessage( $this ) ) ) . 00138 '</p><p>Backtrace:</p><p>' . 00139 nl2br( htmlspecialchars( MWExceptionHandler::getRedactedTraceAsString( $this ) ) ) . 00140 "</p>\n"; 00141 } else { 00142 return "<div class=\"errorbox\">" . 00143 '[' . MWExceptionHandler::getLogId( $this ) . '] ' . 00144 gmdate( 'Y-m-d H:i:s' ) . 00145 ": Fatal exception of type " . get_class( $this ) . "</div>\n" . 00146 "<!-- Set \$wgShowExceptionDetails = true; " . 00147 "at the bottom of LocalSettings.php to show detailed " . 00148 "debugging information. -->"; 00149 } 00150 } 00151 00159 public function getText() { 00160 global $wgShowExceptionDetails; 00161 00162 if ( $wgShowExceptionDetails ) { 00163 return MWExceptionHandler::getLogMessage( $this ) . 00164 "\nBacktrace:\n" . MWExceptionHandler::getRedactedTraceAsString( $this ) . "\n"; 00165 } else { 00166 return "Set \$wgShowExceptionDetails = true; " . 00167 "in LocalSettings.php to show detailed debugging information.\n"; 00168 } 00169 } 00170 00176 public function getPageTitle() { 00177 return $this->msg( 'internalerror', 'Internal error' ); 00178 } 00179 00183 public function reportHTML() { 00184 global $wgOut, $wgSitename; 00185 if ( $this->useOutputPage() ) { 00186 $wgOut->prepareErrorPage( $this->getPageTitle() ); 00187 00188 $hookResult = $this->runHooks( get_class( $this ) ); 00189 if ( $hookResult ) { 00190 $wgOut->addHTML( $hookResult ); 00191 } else { 00192 $wgOut->addHTML( $this->getHTML() ); 00193 } 00194 00195 $wgOut->output(); 00196 } else { 00197 self::header( 'Content-Type: text/html; charset=utf-8' ); 00198 echo "<!DOCTYPE html>\n" . 00199 '<html><head>' . 00200 // Mimick OutputPage::setPageTitle behaviour 00201 '<title>' . 00202 htmlspecialchars( $this->msg( 'pagetitle', "$1 - $wgSitename", $this->getPageTitle() ) ) . 00203 '</title>' . 00204 '<style>body { font-family: sans-serif; margin: 0; padding: 0.5em 2em; }</style>' . 00205 "</head><body>\n"; 00206 00207 $hookResult = $this->runHooks( get_class( $this ) . 'Raw' ); 00208 if ( $hookResult ) { 00209 echo $hookResult; 00210 } else { 00211 echo $this->getHTML(); 00212 } 00213 00214 echo "</body></html>\n"; 00215 } 00216 } 00217 00222 public function report() { 00223 global $wgMimeType; 00224 00225 MWExceptionHandler::logException( $this ); 00226 00227 if ( defined( 'MW_API' ) ) { 00228 // Unhandled API exception, we can't be sure that format printer is alive 00229 self::header( 'MediaWiki-API-Error: internal_api_error_' . get_class( $this ) ); 00230 wfHttpError( 500, 'Internal Server Error', $this->getText() ); 00231 } elseif ( self::isCommandLine() ) { 00232 MWExceptionHandler::printError( $this->getText() ); 00233 } else { 00234 self::header( 'HTTP/1.1 500 MediaWiki exception' ); 00235 self::header( 'Status: 500 MediaWiki exception' ); 00236 self::header( "Content-Type: $wgMimeType; charset=utf-8" ); 00237 00238 $this->reportHTML(); 00239 } 00240 } 00241 00248 public static function isCommandLine() { 00249 return !empty( $GLOBALS['wgCommandLineMode'] ); 00250 } 00251 00257 private static function header( $header ) { 00258 if ( !headers_sent() ) { 00259 header( $header ); 00260 } 00261 } 00262 }