MediaWiki
REL1_23
|
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>' . nl2br( htmlspecialchars( MWExceptionHandler::getRedactedTraceAsString( $this ) ) ) . 00139 "</p>\n"; 00140 } else { 00141 return "<div class=\"errorbox\">" . 00142 '[' . MWExceptionHandler::getLogId( $this ) . '] ' . 00143 gmdate( 'Y-m-d H:i:s' ) . 00144 ": Fatal exception of type " . get_class( $this ) . "</div>\n" . 00145 "<!-- Set \$wgShowExceptionDetails = true; " . 00146 "at the bottom of LocalSettings.php to show detailed " . 00147 "debugging information. -->"; 00148 } 00149 } 00150 00158 public function getText() { 00159 global $wgShowExceptionDetails; 00160 00161 if ( $wgShowExceptionDetails ) { 00162 return MWExceptionHandler::getLogMessage( $this ) . 00163 "\nBacktrace:\n" . MWExceptionHandler::getRedactedTraceAsString( $this ) . "\n"; 00164 } else { 00165 return "Set \$wgShowExceptionDetails = true; " . 00166 "in LocalSettings.php to show detailed debugging information.\n"; 00167 } 00168 } 00169 00175 public function getPageTitle() { 00176 return $this->msg( 'internalerror', 'Internal error' ); 00177 } 00178 00186 public function getLogId() { 00187 wfDeprecated( __METHOD__, '1.22' ); 00188 return MWExceptionHandler::getLogId( $this ); 00189 } 00190 00199 public function getLogMessage() { 00200 wfDeprecated( __METHOD__, '1.22' ); 00201 return MWExceptionHandler::getLogMessage( $this ); 00202 } 00203 00207 public function reportHTML() { 00208 global $wgOut, $wgSitename; 00209 if ( $this->useOutputPage() ) { 00210 $wgOut->prepareErrorPage( $this->getPageTitle() ); 00211 00212 $hookResult = $this->runHooks( get_class( $this ) ); 00213 if ( $hookResult ) { 00214 $wgOut->addHTML( $hookResult ); 00215 } else { 00216 $wgOut->addHTML( $this->getHTML() ); 00217 } 00218 00219 $wgOut->output(); 00220 } else { 00221 header( 'Content-Type: text/html; charset=utf-8' ); 00222 echo "<!DOCTYPE html>\n" . 00223 '<html><head>' . 00224 // Mimick OutputPage::setPageTitle behaviour 00225 '<title>' . htmlspecialchars( $this->msg( 'pagetitle', "$1 - $wgSitename", $this->getPageTitle() ) ) . '</title>' . 00226 '<style>body { font-family: sans-serif; margin: 0; padding: 0.5em 2em; }</style>' . 00227 "</head><body>\n"; 00228 00229 $hookResult = $this->runHooks( get_class( $this ) . 'Raw' ); 00230 if ( $hookResult ) { 00231 echo $hookResult; 00232 } else { 00233 echo $this->getHTML(); 00234 } 00235 00236 echo "</body></html>\n"; 00237 } 00238 } 00239 00244 public function report() { 00245 global $wgMimeType; 00246 00247 MWExceptionHandler::logException( $this ); 00248 00249 if ( defined( 'MW_API' ) ) { 00250 // Unhandled API exception, we can't be sure that format printer is alive 00251 header( 'MediaWiki-API-Error: internal_api_error_' . get_class( $this ) ); 00252 wfHttpError( 500, 'Internal Server Error', $this->getText() ); 00253 } elseif ( self::isCommandLine() ) { 00254 MWExceptionHandler::printError( $this->getText() ); 00255 } else { 00256 header( 'HTTP/1.1 500 MediaWiki exception' ); 00257 header( 'Status: 500 MediaWiki exception', true ); 00258 header( "Content-Type: $wgMimeType; charset=utf-8", true ); 00259 00260 $this->reportHTML(); 00261 } 00262 } 00263 00270 public static function isCommandLine() { 00271 return !empty( $GLOBALS['wgCommandLineMode'] ); 00272 } 00273 }