2006-06-07 06:40:24 +00:00
|
|
|
<?php
|
2010-08-08 14:23:14 +00:00
|
|
|
/**
|
|
|
|
|
* Exception class and handler
|
|
|
|
|
*
|
|
|
|
|
* @file
|
|
|
|
|
*/
|
|
|
|
|
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
/**
|
|
|
|
|
* @defgroup Exception Exception
|
|
|
|
|
*/
|
2006-06-07 06:40:24 +00:00
|
|
|
|
2007-04-20 08:55:14 +00:00
|
|
|
/**
|
2007-04-21 12:42:27 +00:00
|
|
|
* MediaWiki exception
|
2010-08-08 14:23:14 +00:00
|
|
|
*
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
* @ingroup Exception
|
2007-04-20 08:55:14 +00:00
|
|
|
*/
|
2008-03-21 16:56:44 +00:00
|
|
|
class MWException extends Exception {
|
|
|
|
|
/**
|
|
|
|
|
* Should the exception use $wgOut to output the error ?
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2006-06-07 06:40:24 +00:00
|
|
|
function useOutputPage() {
|
* Introduced a new system for localisation caching. The system is based around fast fetches of individual messages, minimising memory overhead and startup time in the typical case. It handles both core messages (formerly in Language.php) and extension messages (formerly in MessageCache.php). Profiling indicates a significant win for average throughput.
* The serialized message cache, which would have been redundant, has been removed. Similar performance characteristics can be achieved with $wgLocalisationCacheConf['manualRecache'] = true;
* Added a maintenance script rebuildLocalisationCache.php for offline rebuilding of the localisation cache.
* Extension i18n files can now contain any of the variables which can be set in Messages*.php. It is possible, and recommended, to use this feature instead of the hooks for special page aliases and magic words.
* $wgExtensionAliasesFiles, LanguageGetMagic and LanguageGetSpecialPageAliases are retained for backwards compatibility. $wgMessageCache->addMessages() and related functions have been removed. wfLoadExtensionMessages() is a no-op and can continue to be called for b/c.
* Introduced $wgCacheDirectory as a default location for the various local caches that have accumulated. Suggested $IP/cache as a good place for it in the default LocalSettings.php and created this directory with a deny-all .htaccess.
* Patched Exception.php to avoid using the message cache when an exception is thrown from within LocalisationCache, since this tends to fail horribly.
* Removed Language::getLocalisationArray(), Language::loadLocalisation(), Language::load()
* Fixed FileDependency::__sleep()
* In Cdb.php, fixed newlines in debug messages
In MessageCache::get():
* Replaced calls to $wgContLang capitalisation functions with plain PHP functions, reducing the typical case from 99us to 93us. Message cache keys are already documented as being restricted to ASCII.
* Implemented a more efficient way to filter out bogus language codes, reducing the "foo/en" case from 430us to 101us
* Optimised wfRunHooks() in the typical do-nothing case, from ~30us to ~3us. This reduced MessageCache::get() typical case time from 93us to 38us.
* Removed hook MessageNotInMwNs to save an extra 3us per cache hit. Reimplemented the only user (LocalisationUpdate) using the new hook LocalisationCacheRecache.
2009-06-28 07:11:43 +00:00
|
|
|
return $this->useMessageCache() &&
|
|
|
|
|
!empty( $GLOBALS['wgFullyInitialised'] ) &&
|
2011-05-22 17:59:47 +00:00
|
|
|
!empty( $GLOBALS['wgOut'] ) &&
|
2008-04-16 16:17:44 +00:00
|
|
|
!empty( $GLOBALS['wgTitle'] );
|
2006-06-07 06:40:24 +00:00
|
|
|
}
|
|
|
|
|
|
2008-03-21 16:56:44 +00:00
|
|
|
/**
|
|
|
|
|
* Can the extension use wfMsg() to get i18n messages ?
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2006-06-07 06:40:24 +00:00
|
|
|
function useMessageCache() {
|
|
|
|
|
global $wgLang;
|
2010-09-04 13:48:16 +00:00
|
|
|
|
* Introduced a new system for localisation caching. The system is based around fast fetches of individual messages, minimising memory overhead and startup time in the typical case. It handles both core messages (formerly in Language.php) and extension messages (formerly in MessageCache.php). Profiling indicates a significant win for average throughput.
* The serialized message cache, which would have been redundant, has been removed. Similar performance characteristics can be achieved with $wgLocalisationCacheConf['manualRecache'] = true;
* Added a maintenance script rebuildLocalisationCache.php for offline rebuilding of the localisation cache.
* Extension i18n files can now contain any of the variables which can be set in Messages*.php. It is possible, and recommended, to use this feature instead of the hooks for special page aliases and magic words.
* $wgExtensionAliasesFiles, LanguageGetMagic and LanguageGetSpecialPageAliases are retained for backwards compatibility. $wgMessageCache->addMessages() and related functions have been removed. wfLoadExtensionMessages() is a no-op and can continue to be called for b/c.
* Introduced $wgCacheDirectory as a default location for the various local caches that have accumulated. Suggested $IP/cache as a good place for it in the default LocalSettings.php and created this directory with a deny-all .htaccess.
* Patched Exception.php to avoid using the message cache when an exception is thrown from within LocalisationCache, since this tends to fail horribly.
* Removed Language::getLocalisationArray(), Language::loadLocalisation(), Language::load()
* Fixed FileDependency::__sleep()
* In Cdb.php, fixed newlines in debug messages
In MessageCache::get():
* Replaced calls to $wgContLang capitalisation functions with plain PHP functions, reducing the typical case from 99us to 93us. Message cache keys are already documented as being restricted to ASCII.
* Implemented a more efficient way to filter out bogus language codes, reducing the "foo/en" case from 430us to 101us
* Optimised wfRunHooks() in the typical do-nothing case, from ~30us to ~3us. This reduced MessageCache::get() typical case time from 93us to 38us.
* Removed hook MessageNotInMwNs to save an extra 3us per cache hit. Reimplemented the only user (LocalisationUpdate) using the new hook LocalisationCacheRecache.
2009-06-28 07:11:43 +00:00
|
|
|
foreach ( $this->getTrace() as $frame ) {
|
2009-07-03 06:19:39 +00:00
|
|
|
if ( isset( $frame['class'] ) && $frame['class'] === 'LocalisationCache' ) {
|
* Introduced a new system for localisation caching. The system is based around fast fetches of individual messages, minimising memory overhead and startup time in the typical case. It handles both core messages (formerly in Language.php) and extension messages (formerly in MessageCache.php). Profiling indicates a significant win for average throughput.
* The serialized message cache, which would have been redundant, has been removed. Similar performance characteristics can be achieved with $wgLocalisationCacheConf['manualRecache'] = true;
* Added a maintenance script rebuildLocalisationCache.php for offline rebuilding of the localisation cache.
* Extension i18n files can now contain any of the variables which can be set in Messages*.php. It is possible, and recommended, to use this feature instead of the hooks for special page aliases and magic words.
* $wgExtensionAliasesFiles, LanguageGetMagic and LanguageGetSpecialPageAliases are retained for backwards compatibility. $wgMessageCache->addMessages() and related functions have been removed. wfLoadExtensionMessages() is a no-op and can continue to be called for b/c.
* Introduced $wgCacheDirectory as a default location for the various local caches that have accumulated. Suggested $IP/cache as a good place for it in the default LocalSettings.php and created this directory with a deny-all .htaccess.
* Patched Exception.php to avoid using the message cache when an exception is thrown from within LocalisationCache, since this tends to fail horribly.
* Removed Language::getLocalisationArray(), Language::loadLocalisation(), Language::load()
* Fixed FileDependency::__sleep()
* In Cdb.php, fixed newlines in debug messages
In MessageCache::get():
* Replaced calls to $wgContLang capitalisation functions with plain PHP functions, reducing the typical case from 99us to 93us. Message cache keys are already documented as being restricted to ASCII.
* Implemented a more efficient way to filter out bogus language codes, reducing the "foo/en" case from 430us to 101us
* Optimised wfRunHooks() in the typical do-nothing case, from ~30us to ~3us. This reduced MessageCache::get() typical case time from 93us to 38us.
* Removed hook MessageNotInMwNs to save an extra 3us per cache hit. Reimplemented the only user (LocalisationUpdate) using the new hook LocalisationCacheRecache.
2009-06-28 07:11:43 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-09-04 13:48:16 +00:00
|
|
|
|
2011-01-09 18:31:52 +00:00
|
|
|
return $wgLang instanceof Language;
|
2006-06-07 06:40:24 +00:00
|
|
|
}
|
|
|
|
|
|
2008-03-21 16:56:44 +00:00
|
|
|
/**
|
|
|
|
|
* Run hook to allow extensions to modify the text of the exception
|
|
|
|
|
*
|
2010-03-05 21:39:21 +00:00
|
|
|
* @param $name String: class name of the exception
|
|
|
|
|
* @param $args Array: arguments to pass to the callback functions
|
|
|
|
|
* @return Mixed: string to output or null if any hook has been called
|
2008-03-21 16:56:44 +00:00
|
|
|
*/
|
2008-01-08 18:34:06 +00:00
|
|
|
function runHooks( $name, $args = array() ) {
|
|
|
|
|
global $wgExceptionHooks;
|
2010-09-04 13:48:16 +00:00
|
|
|
|
|
|
|
|
if ( !isset( $wgExceptionHooks ) || !is_array( $wgExceptionHooks ) ) {
|
2011-10-14 21:18:38 +00:00
|
|
|
return; // Just silently ignore
|
2010-09-04 13:48:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( !array_key_exists( $name, $wgExceptionHooks ) || !is_array( $wgExceptionHooks[ $name ] ) ) {
|
2008-01-08 18:34:06 +00:00
|
|
|
return;
|
2010-09-04 13:48:16 +00:00
|
|
|
}
|
|
|
|
|
|
2008-01-08 18:34:06 +00:00
|
|
|
$hooks = $wgExceptionHooks[ $name ];
|
|
|
|
|
$callargs = array_merge( array( $this ), $args );
|
|
|
|
|
|
2010-09-04 13:48:16 +00:00
|
|
|
foreach ( $hooks as $hook ) {
|
|
|
|
|
if ( is_string( $hook ) || ( is_array( $hook ) && count( $hook ) >= 2 && is_string( $hook[0] ) ) ) { // 'function' or array( 'class', hook' )
|
2008-01-08 18:34:06 +00:00
|
|
|
$result = call_user_func_array( $hook, $callargs );
|
|
|
|
|
} else {
|
|
|
|
|
$result = null;
|
|
|
|
|
}
|
2010-09-04 13:48:16 +00:00
|
|
|
|
2011-10-16 03:27:12 +00:00
|
|
|
if ( is_string( $result ) ) {
|
2008-01-08 18:34:06 +00:00
|
|
|
return $result;
|
2011-10-16 03:27:12 +00:00
|
|
|
}
|
2008-01-08 18:34:06 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-03-21 16:56:44 +00:00
|
|
|
/**
|
|
|
|
|
* Get a message from i18n
|
|
|
|
|
*
|
2010-03-05 21:39:21 +00:00
|
|
|
* @param $key String: message name
|
|
|
|
|
* @param $fallback String: default message if the message cache can't be
|
|
|
|
|
* called by the exception
|
2008-03-21 16:56:44 +00:00
|
|
|
* The function also has other parameters that are arguments for the message
|
|
|
|
|
* @return String message with arguments replaced
|
|
|
|
|
*/
|
2006-06-07 06:40:24 +00:00
|
|
|
function msg( $key, $fallback /*[, params...] */ ) {
|
|
|
|
|
$args = array_slice( func_get_args(), 2 );
|
2010-09-04 13:48:16 +00:00
|
|
|
|
2006-06-07 06:40:24 +00:00
|
|
|
if ( $this->useMessageCache() ) {
|
2011-04-24 16:53:46 +00:00
|
|
|
return wfMsgNoTrans( $key, $args );
|
2006-06-07 06:40:24 +00:00
|
|
|
} else {
|
|
|
|
|
return wfMsgReplaceArgs( $fallback, $args );
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-10-11 18:57:49 +00:00
|
|
|
|
2008-03-21 16:56:44 +00:00
|
|
|
/**
|
2008-04-14 07:45:50 +00:00
|
|
|
* If $wgShowExceptionDetails is true, return a HTML message with a
|
2008-03-21 16:56:44 +00:00
|
|
|
* backtrace to the error, otherwise show a message to ask to set it to true
|
|
|
|
|
* to show that information.
|
|
|
|
|
*
|
|
|
|
|
* @return String html to output
|
|
|
|
|
*/
|
2006-06-07 06:40:24 +00:00
|
|
|
function getHTML() {
|
2006-10-11 18:57:49 +00:00
|
|
|
global $wgShowExceptionDetails;
|
2010-09-04 13:48:16 +00:00
|
|
|
|
|
|
|
|
if ( $wgShowExceptionDetails ) {
|
2008-08-26 14:37:15 +00:00
|
|
|
return '<p>' . nl2br( htmlspecialchars( $this->getMessage() ) ) .
|
2006-10-11 18:57:49 +00:00
|
|
|
'</p><p>Backtrace:</p><p>' . nl2br( htmlspecialchars( $this->getTraceAsString() ) ) .
|
|
|
|
|
"</p>\n";
|
|
|
|
|
} else {
|
|
|
|
|
return "<p>Set <b><tt>\$wgShowExceptionDetails = true;</tt></b> " .
|
2007-09-30 00:19:43 +00:00
|
|
|
"at the bottom of LocalSettings.php to show detailed " .
|
|
|
|
|
"debugging information.</p>";
|
2006-10-11 18:57:49 +00:00
|
|
|
}
|
2006-06-07 06:40:24 +00:00
|
|
|
}
|
|
|
|
|
|
2008-03-21 16:56:44 +00:00
|
|
|
/**
|
2008-04-14 07:45:50 +00:00
|
|
|
* If $wgShowExceptionDetails is true, return a text message with a
|
2008-03-21 16:56:44 +00:00
|
|
|
* backtrace to the error.
|
2011-10-26 03:44:47 +00:00
|
|
|
* @return string
|
2008-03-21 16:56:44 +00:00
|
|
|
*/
|
2006-06-07 06:40:24 +00:00
|
|
|
function getText() {
|
2006-10-11 18:57:49 +00:00
|
|
|
global $wgShowExceptionDetails;
|
2010-09-04 13:48:16 +00:00
|
|
|
|
|
|
|
|
if ( $wgShowExceptionDetails ) {
|
2006-10-11 18:57:49 +00:00
|
|
|
return $this->getMessage() .
|
|
|
|
|
"\nBacktrace:\n" . $this->getTraceAsString() . "\n";
|
|
|
|
|
} else {
|
2008-05-06 02:50:07 +00:00
|
|
|
return "Set \$wgShowExceptionDetails = true; " .
|
|
|
|
|
"in LocalSettings.php to show detailed debugging information.\n";
|
2006-10-11 18:57:49 +00:00
|
|
|
}
|
2006-06-07 06:40:24 +00:00
|
|
|
}
|
2007-04-21 12:42:27 +00:00
|
|
|
|
2011-10-11 18:30:50 +00:00
|
|
|
/**
|
|
|
|
|
* Return titles of this error page
|
|
|
|
|
* @return String
|
|
|
|
|
*/
|
2006-06-07 06:40:24 +00:00
|
|
|
function getPageTitle() {
|
2011-10-28 15:45:54 +00:00
|
|
|
return $this->msg( 'internalerror', "Internal error" );
|
2006-06-07 06:40:24 +00:00
|
|
|
}
|
2007-04-21 12:42:27 +00:00
|
|
|
|
2008-03-21 16:56:44 +00:00
|
|
|
/**
|
|
|
|
|
* Return the requested URL and point to file and line number from which the
|
2007-04-21 12:42:27 +00:00
|
|
|
* exception occured
|
2008-03-21 16:56:44 +00:00
|
|
|
*
|
2010-03-05 21:39:21 +00:00
|
|
|
* @return String
|
2007-04-21 12:42:27 +00:00
|
|
|
*/
|
2006-08-02 17:40:09 +00:00
|
|
|
function getLogMessage() {
|
2007-01-16 01:45:51 +00:00
|
|
|
global $wgRequest;
|
2010-09-04 13:48:16 +00:00
|
|
|
|
2006-08-02 17:40:09 +00:00
|
|
|
$file = $this->getFile();
|
|
|
|
|
$line = $this->getLine();
|
|
|
|
|
$message = $this->getMessage();
|
2010-09-04 13:48:16 +00:00
|
|
|
|
2011-09-16 15:21:06 +00:00
|
|
|
if ( isset( $wgRequest ) && !$wgRequest instanceof FauxRequest ) {
|
2008-09-21 09:38:55 +00:00
|
|
|
$url = $wgRequest->getRequestURL();
|
|
|
|
|
if ( !$url ) {
|
|
|
|
|
$url = '[no URL]';
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$url = '[no req]';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return "$url Exception from line $line of $file: $message";
|
2006-08-02 17:40:09 +00:00
|
|
|
}
|
2007-04-21 12:42:27 +00:00
|
|
|
|
|
|
|
|
/** Output the exception report using HTML */
|
2006-06-07 06:40:24 +00:00
|
|
|
function reportHTML() {
|
|
|
|
|
global $wgOut;
|
|
|
|
|
if ( $this->useOutputPage() ) {
|
2011-10-28 15:45:54 +00:00
|
|
|
$wgOut->prepareErrorPage( $this->getPageTitle() );
|
2010-09-04 13:48:16 +00:00
|
|
|
|
2010-11-01 00:07:17 +00:00
|
|
|
$hookResult = $this->runHooks( get_class( $this ) );
|
|
|
|
|
if ( $hookResult ) {
|
2008-01-08 18:34:06 +00:00
|
|
|
$wgOut->addHTML( $hookResult );
|
|
|
|
|
} else {
|
|
|
|
|
$wgOut->addHTML( $this->getHTML() );
|
|
|
|
|
}
|
2010-09-04 13:48:16 +00:00
|
|
|
|
2006-06-07 06:40:24 +00:00
|
|
|
$wgOut->output();
|
|
|
|
|
} else {
|
2010-11-01 00:07:17 +00:00
|
|
|
$hookResult = $this->runHooks( get_class( $this ) . "Raw" );
|
|
|
|
|
if ( $hookResult ) {
|
2008-01-08 18:34:06 +00:00
|
|
|
die( $hookResult );
|
|
|
|
|
}
|
2010-09-04 13:48:16 +00:00
|
|
|
|
2011-06-28 19:46:23 +00:00
|
|
|
echo $this->getHTML();
|
|
|
|
|
die(1);
|
2006-06-07 06:40:24 +00:00
|
|
|
}
|
|
|
|
|
}
|
2007-04-21 12:42:27 +00:00
|
|
|
|
2008-03-21 16:56:44 +00:00
|
|
|
/**
|
|
|
|
|
* Output a report about the exception and takes care of formatting.
|
2009-01-15 06:56:58 +00:00
|
|
|
* It will be either HTML or plain text based on isCommandLine().
|
2007-04-21 12:42:27 +00:00
|
|
|
*/
|
2006-06-07 06:40:24 +00:00
|
|
|
function report() {
|
2008-07-07 03:31:00 +00:00
|
|
|
$log = $this->getLogMessage();
|
2010-09-04 13:48:16 +00:00
|
|
|
|
2008-07-07 03:31:00 +00:00
|
|
|
if ( $log ) {
|
|
|
|
|
wfDebugLog( 'exception', $log );
|
|
|
|
|
}
|
2010-09-04 13:48:16 +00:00
|
|
|
|
2009-01-15 06:56:58 +00:00
|
|
|
if ( self::isCommandLine() ) {
|
2011-05-30 00:18:10 +00:00
|
|
|
MWExceptionHandler::printError( $this->getText() );
|
2006-06-07 06:40:24 +00:00
|
|
|
} else {
|
|
|
|
|
$this->reportHTML();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-26 03:44:47 +00:00
|
|
|
/**
|
|
|
|
|
* @static
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2009-01-15 06:56:58 +00:00
|
|
|
static function isCommandLine() {
|
2011-06-28 19:46:23 +00:00
|
|
|
return !empty( $GLOBALS['wgCommandLineMode'] );
|
2009-01-15 06:56:58 +00:00
|
|
|
}
|
2006-06-07 06:40:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2006-07-11 17:40:11 +00:00
|
|
|
* Exception class which takes an HTML error message, and does not
|
2006-06-07 06:40:24 +00:00
|
|
|
* produce a backtrace. Replacement for OutputPage::fatalError().
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
* @ingroup Exception
|
2006-06-07 06:40:24 +00:00
|
|
|
*/
|
|
|
|
|
class FatalError extends MWException {
|
2011-10-26 03:44:47 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2006-06-07 06:40:24 +00:00
|
|
|
function getHTML() {
|
|
|
|
|
return $this->getMessage();
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-26 03:44:47 +00:00
|
|
|
/**
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2006-06-07 06:40:24 +00:00
|
|
|
function getText() {
|
|
|
|
|
return $this->getMessage();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-04-20 08:55:14 +00:00
|
|
|
/**
|
2011-04-12 22:59:17 +00:00
|
|
|
* An error page which can definitely be safely rendered using the OutputPage
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
* @ingroup Exception
|
2007-04-20 08:55:14 +00:00
|
|
|
*/
|
2006-06-07 06:40:24 +00:00
|
|
|
class ErrorPageError extends MWException {
|
2011-04-12 22:59:17 +00:00
|
|
|
public $title, $msg, $params;
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2006-06-07 06:40:24 +00:00
|
|
|
/**
|
|
|
|
|
* Note: these arguments are keys into wfMsg(), not text!
|
|
|
|
|
*/
|
2011-04-12 22:59:17 +00:00
|
|
|
function __construct( $title, $msg, $params = null ) {
|
2006-06-07 06:40:24 +00:00
|
|
|
$this->title = $title;
|
|
|
|
|
$this->msg = $msg;
|
2011-04-12 22:59:17 +00:00
|
|
|
$this->params = $params;
|
2011-04-13 22:30:13 +00:00
|
|
|
|
|
|
|
|
if( $msg instanceof Message ){
|
|
|
|
|
parent::__construct( $msg );
|
|
|
|
|
} else {
|
|
|
|
|
parent::__construct( wfMsg( $msg ) );
|
|
|
|
|
}
|
2006-06-07 06:40:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function report() {
|
|
|
|
|
global $wgOut;
|
2010-09-04 13:48:16 +00:00
|
|
|
|
2011-08-25 10:13:30 +00:00
|
|
|
$wgOut->showErrorPage( $this->title, $this->msg, $this->params );
|
2006-06-07 06:40:24 +00:00
|
|
|
$wgOut->output();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-12 22:59:17 +00:00
|
|
|
/**
|
|
|
|
|
* Show an error when a user tries to do something they do not have the necessary
|
|
|
|
|
* permissions for.
|
2011-05-30 00:21:06 +00:00
|
|
|
* @ingroup Exception
|
2011-04-12 22:59:17 +00:00
|
|
|
*/
|
|
|
|
|
class PermissionsError extends ErrorPageError {
|
2011-11-02 15:30:55 +00:00
|
|
|
public $permission, $errors;
|
2011-04-12 22:59:17 +00:00
|
|
|
|
2011-11-02 15:30:55 +00:00
|
|
|
function __construct( $permission, $errors = array() ) {
|
2011-04-12 22:59:17 +00:00
|
|
|
global $wgLang;
|
|
|
|
|
|
|
|
|
|
$this->permission = $permission;
|
|
|
|
|
|
2011-11-02 15:30:55 +00:00
|
|
|
if ( !count( $errors ) ) {
|
|
|
|
|
$groups = array_map(
|
|
|
|
|
array( 'User', 'makeGroupLinkWiki' ),
|
|
|
|
|
User::getGroupsWithPermission( $this->permission )
|
2011-04-12 22:59:17 +00:00
|
|
|
);
|
2011-11-02 15:30:55 +00:00
|
|
|
|
|
|
|
|
if ( $groups ) {
|
|
|
|
|
$errors[] = array( 'badaccess-groups', $wgLang->commaList( $groups ), count( $groups ) );
|
|
|
|
|
} else {
|
|
|
|
|
$errors[] = array( 'badaccess-group0' );
|
|
|
|
|
}
|
2011-04-12 22:59:17 +00:00
|
|
|
}
|
2011-11-02 15:30:55 +00:00
|
|
|
|
|
|
|
|
$this->errors = $errors;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function report() {
|
|
|
|
|
global $wgOut;
|
|
|
|
|
|
|
|
|
|
$wgOut->showPermissionsErrorPage( $this->errors, $this->permission );
|
|
|
|
|
$wgOut->output();
|
2011-04-12 22:59:17 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-13 14:30:55 +00:00
|
|
|
/**
|
|
|
|
|
* Show an error when the wiki is locked/read-only and the user tries to do
|
|
|
|
|
* something that requires write access
|
2011-05-30 00:21:06 +00:00
|
|
|
* @ingroup Exception
|
2011-04-13 14:30:55 +00:00
|
|
|
*/
|
|
|
|
|
class ReadOnlyError extends ErrorPageError {
|
|
|
|
|
public function __construct(){
|
|
|
|
|
parent::__construct(
|
|
|
|
|
'readonly',
|
|
|
|
|
'readonlytext',
|
|
|
|
|
wfReadOnlyReason()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-18 22:29:23 +00:00
|
|
|
/**
|
|
|
|
|
* Show an error when the user hits a rate limit
|
2011-05-30 00:21:06 +00:00
|
|
|
* @ingroup Exception
|
2011-04-18 22:29:23 +00:00
|
|
|
*/
|
|
|
|
|
class ThrottledError extends ErrorPageError {
|
|
|
|
|
public function __construct(){
|
|
|
|
|
parent::__construct(
|
|
|
|
|
'actionthrottled',
|
|
|
|
|
'actionthrottledtext'
|
|
|
|
|
);
|
|
|
|
|
}
|
2011-10-26 03:44:47 +00:00
|
|
|
|
2011-04-18 22:29:23 +00:00
|
|
|
public function report(){
|
|
|
|
|
global $wgOut;
|
|
|
|
|
$wgOut->setStatusCode( 503 );
|
|
|
|
|
return parent::report();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-13 14:30:55 +00:00
|
|
|
/**
|
|
|
|
|
* Show an error when the user tries to do something whilst blocked
|
2011-05-30 00:21:06 +00:00
|
|
|
* @ingroup Exception
|
2011-04-13 14:30:55 +00:00
|
|
|
*/
|
|
|
|
|
class UserBlockedError extends ErrorPageError {
|
|
|
|
|
public function __construct( Block $block ){
|
2011-08-18 20:03:30 +00:00
|
|
|
global $wgLang, $wgRequest;
|
2011-04-13 14:30:55 +00:00
|
|
|
|
2011-11-01 00:11:53 +00:00
|
|
|
$blocker = $block->getBlocker();
|
|
|
|
|
if ( $blocker instanceof User ) { // local user
|
|
|
|
|
$blockerUserpage = $block->getBlocker()->getUserPage();
|
|
|
|
|
$link = "[[{$blockerUserpage->getPrefixedText()}|{$blockerUserpage->getText()}]]";
|
|
|
|
|
} else { // foreign user
|
|
|
|
|
$link = $blocker;
|
|
|
|
|
}
|
2011-04-13 14:30:55 +00:00
|
|
|
|
|
|
|
|
$reason = $block->mReason;
|
|
|
|
|
if( $reason == '' ) {
|
|
|
|
|
$reason = wfMsg( 'blockednoreason' );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* $ip returns who *is* being blocked, $intended contains who was meant to be blocked.
|
|
|
|
|
* This could be a username, an IP range, or a single IP. */
|
|
|
|
|
$intended = $block->getTarget();
|
|
|
|
|
|
|
|
|
|
parent::__construct(
|
|
|
|
|
'blockedtitle',
|
2011-07-27 19:46:56 +00:00
|
|
|
$block->mAuto ? 'autoblockedtext' : 'blockedtext',
|
2011-04-13 14:30:55 +00:00
|
|
|
array(
|
|
|
|
|
$link,
|
|
|
|
|
$reason,
|
2011-08-18 20:03:30 +00:00
|
|
|
$wgRequest->getIP(),
|
2011-11-01 00:16:35 +00:00
|
|
|
$block->getByName(),
|
2011-04-13 14:30:55 +00:00
|
|
|
$block->getId(),
|
|
|
|
|
$wgLang->formatExpiry( $block->mExpiry ),
|
|
|
|
|
$intended,
|
|
|
|
|
$wgLang->timeanddate( wfTimestamp( TS_MW, $block->mTimestamp ), true )
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-16 18:50:13 +00:00
|
|
|
/**
|
|
|
|
|
* Show an error that looks like an HTTP server error.
|
|
|
|
|
* Replacement for wfHttpError().
|
|
|
|
|
*
|
|
|
|
|
* @ingroup Exception
|
|
|
|
|
*/
|
|
|
|
|
class HttpError extends MWException {
|
|
|
|
|
private $httpCode, $header, $content;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Constructor
|
|
|
|
|
*
|
|
|
|
|
* @param $httpCode Integer: HTTP status code to send to the client
|
|
|
|
|
* @param $content String|Message: content of the message
|
|
|
|
|
* @param $header String|Message: content of the header (\<title\> and \<h1\>)
|
|
|
|
|
*/
|
|
|
|
|
public function __construct( $httpCode, $content, $header = null ){
|
|
|
|
|
parent::__construct( $content );
|
|
|
|
|
$this->httpCode = (int)$httpCode;
|
|
|
|
|
$this->header = $header;
|
|
|
|
|
$this->content = $content;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function reportHTML() {
|
|
|
|
|
$httpMessage = HttpStatus::getMessage( $this->httpCode );
|
|
|
|
|
|
|
|
|
|
header( "Status: {$this->httpCode} {$httpMessage}" );
|
|
|
|
|
header( 'Content-type: text/html; charset=utf-8' );
|
|
|
|
|
|
|
|
|
|
if ( $this->header === null ) {
|
|
|
|
|
$header = $httpMessage;
|
|
|
|
|
} elseif ( $this->header instanceof Message ) {
|
|
|
|
|
$header = $this->header->escaped();
|
|
|
|
|
} else {
|
|
|
|
|
$header = htmlspecialchars( $this->header );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( $this->content instanceof Message ) {
|
|
|
|
|
$content = $this->content->escaped();
|
|
|
|
|
} else {
|
|
|
|
|
$content = htmlspecialchars( $this->content );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
print "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n".
|
|
|
|
|
"<html><head><title>$header</title></head>\n" .
|
|
|
|
|
"<body><h1>$header</h1><p>$content</p></body></html>\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-06-07 06:40:24 +00:00
|
|
|
/**
|
2011-05-30 00:18:10 +00:00
|
|
|
* Handler class for MWExceptions
|
2011-05-30 00:21:06 +00:00
|
|
|
* @ingroup Exception
|
2006-06-07 06:40:24 +00:00
|
|
|
*/
|
2011-05-30 00:18:10 +00:00
|
|
|
class MWExceptionHandler {
|
|
|
|
|
/**
|
|
|
|
|
* Install an exception handler for MediaWiki exception types.
|
|
|
|
|
*/
|
|
|
|
|
public static function installHandler() {
|
|
|
|
|
set_exception_handler( array( 'MWExceptionHandler', 'handle' ) );
|
|
|
|
|
}
|
2010-08-07 18:32:39 +00:00
|
|
|
|
2011-05-30 00:18:10 +00:00
|
|
|
/**
|
|
|
|
|
* Report an exception to the user
|
|
|
|
|
*/
|
|
|
|
|
protected static function report( Exception $e ) {
|
|
|
|
|
global $wgShowExceptionDetails;
|
2010-09-04 13:48:16 +00:00
|
|
|
|
2011-05-30 00:18:10 +00:00
|
|
|
$cmdLine = MWException::isCommandLine();
|
|
|
|
|
|
|
|
|
|
if ( $e instanceof MWException ) {
|
|
|
|
|
try {
|
|
|
|
|
// Try and show the exception prettily, with the normal skin infrastructure
|
|
|
|
|
$e->report();
|
|
|
|
|
} catch ( Exception $e2 ) {
|
|
|
|
|
// Exception occurred from within exception handler
|
|
|
|
|
// Show a simpler error message for the original exception,
|
|
|
|
|
// don't try to invoke report()
|
|
|
|
|
$message = "MediaWiki internal error.\n\n";
|
|
|
|
|
|
|
|
|
|
if ( $wgShowExceptionDetails ) {
|
|
|
|
|
$message .= 'Original exception: ' . $e->__toString() . "\n\n" .
|
|
|
|
|
'Exception caught inside exception handler: ' . $e2->__toString();
|
|
|
|
|
} else {
|
|
|
|
|
$message .= "Exception caught inside exception handler.\n\n" .
|
|
|
|
|
"Set \$wgShowExceptionDetails = true; at the bottom of LocalSettings.php " .
|
|
|
|
|
"to show detailed debugging information.";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$message .= "\n";
|
|
|
|
|
|
|
|
|
|
if ( $cmdLine ) {
|
|
|
|
|
self::printError( $message );
|
|
|
|
|
} else {
|
2011-06-28 19:46:23 +00:00
|
|
|
self::escapeEchoAndDie( $message );
|
2011-05-30 00:18:10 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$message = "Unexpected non-MediaWiki exception encountered, of type \"" . get_class( $e ) . "\"\n" .
|
|
|
|
|
$e->__toString() . "\n";
|
2010-09-04 13:48:16 +00:00
|
|
|
|
2010-08-07 18:32:39 +00:00
|
|
|
if ( $wgShowExceptionDetails ) {
|
2011-05-30 00:18:10 +00:00
|
|
|
$message .= "\n" . $e->getTraceAsString() . "\n";
|
2010-08-07 18:32:39 +00:00
|
|
|
}
|
2010-09-04 13:48:16 +00:00
|
|
|
|
2009-02-17 21:14:34 +00:00
|
|
|
if ( $cmdLine ) {
|
2011-05-30 00:18:10 +00:00
|
|
|
self::printError( $message );
|
2009-02-17 21:14:34 +00:00
|
|
|
} else {
|
2011-06-28 19:46:23 +00:00
|
|
|
self::escapeEchoAndDie( $message );
|
2009-04-02 20:38:25 +00:00
|
|
|
}
|
2009-02-17 21:14:34 +00:00
|
|
|
}
|
2011-05-30 00:18:10 +00:00
|
|
|
}
|
2010-09-04 13:48:16 +00:00
|
|
|
|
2011-05-30 00:18:10 +00:00
|
|
|
/**
|
|
|
|
|
* Print a message, if possible to STDERR.
|
|
|
|
|
* Use this in command line mode only (see isCommandLine)
|
2011-06-28 19:46:23 +00:00
|
|
|
* @param $message String Failure text
|
2011-05-30 00:18:10 +00:00
|
|
|
*/
|
|
|
|
|
public static function printError( $message ) {
|
|
|
|
|
# NOTE: STDERR may not be available, especially if php-cgi is used from the command line (bug #15602).
|
|
|
|
|
# Try to produce meaningful output anyway. Using echo may corrupt output to STDOUT though.
|
|
|
|
|
if ( defined( 'STDERR' ) ) {
|
|
|
|
|
fwrite( STDERR, $message );
|
2009-02-16 04:33:22 +00:00
|
|
|
} else {
|
2011-05-30 00:18:10 +00:00
|
|
|
echo( $message );
|
2009-02-16 04:33:22 +00:00
|
|
|
}
|
2009-02-17 21:14:34 +00:00
|
|
|
}
|
2006-06-07 06:40:24 +00:00
|
|
|
|
2011-06-28 19:46:23 +00:00
|
|
|
/**
|
|
|
|
|
* Print a message after escaping it and converting newlines to <br>
|
|
|
|
|
* Use this for non-command line failures
|
|
|
|
|
* @param $message String Failure text
|
|
|
|
|
*/
|
|
|
|
|
private static function escapeEchoAndDie( $message ) {
|
|
|
|
|
echo nl2br( htmlspecialchars( $message ) ) . "\n";
|
|
|
|
|
die(1);
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-30 00:18:10 +00:00
|
|
|
/**
|
|
|
|
|
* Exception handler which simulates the appropriate catch() handling:
|
|
|
|
|
*
|
|
|
|
|
* try {
|
|
|
|
|
* ...
|
|
|
|
|
* } catch ( MWException $e ) {
|
|
|
|
|
* $e->report();
|
|
|
|
|
* } catch ( Exception $e ) {
|
|
|
|
|
* echo $e->__toString();
|
|
|
|
|
* }
|
|
|
|
|
*/
|
|
|
|
|
public static function handle( $e ) {
|
|
|
|
|
global $wgFullyInitialised;
|
2008-09-15 09:53:52 +00:00
|
|
|
|
2011-05-30 00:18:10 +00:00
|
|
|
self::report( $e );
|
2010-09-04 13:48:16 +00:00
|
|
|
|
2011-05-30 00:18:10 +00:00
|
|
|
// Final cleanup
|
|
|
|
|
if ( $wgFullyInitialised ) {
|
|
|
|
|
try {
|
|
|
|
|
wfLogProfilingData(); // uses $wgRequest, hence the $wgFullyInitialised condition
|
|
|
|
|
} catch ( Exception $e ) {}
|
|
|
|
|
}
|
2007-04-21 12:42:27 +00:00
|
|
|
|
2011-05-30 00:18:10 +00:00
|
|
|
// Exit value should be nonzero for the benefit of shell jobs
|
|
|
|
|
exit( 1 );
|
2006-06-07 06:40:24 +00:00
|
|
|
}
|
|
|
|
|
}
|