$this->register( include "$IP/resources/ResourcesOOUI.php" );
// Register extension modules
$this->register( $config->get( 'ResourceModules' ) );
- Hooks::run( 'ResourceLoaderRegisterModules', [ &$this ] );
+
+ // Avoid PHP 7.1 warning from passing $this by reference
+ $rl = $this;
+ Hooks::run( 'ResourceLoaderRegisterModules', [ &$rl ] );
if ( $config->get( 'EnableJavaScriptTest' ) === true ) {
$this->registerTestModules();
}
}
- /**
- */
public function registerTestModules() {
global $IP;
$testModules = [];
$testModules['qunit'] = [];
// Get other test suites (e.g. from extensions)
- Hooks::run( 'ResourceLoaderTestModules', [ &$testModules, &$this ] );
+ // Avoid PHP 7.1 warning from passing $this by reference
+ $rl = $this;
+ Hooks::run( 'ResourceLoaderTestModules', [ &$testModules, &$rl ] );
// Add the testrunner (which configures QUnit) to the dependencies.
// Since it must be ready before any of the test suites are executed.
return Wikimedia\base_convert( $hash, 16, 36, 7 );
}
+ /**
+ * Add an error to the 'errors' array and log it.
+ *
+ * Should only be called from within respond().
+ *
+ * @since 1.29
+ * @param Exception $e
+ * @param string $msg
+ * @param array $context
+ */
+ protected function outputErrorAndLog( Exception $e, $msg, array $context = [] ) {
+ MWExceptionHandler::logException( $e );
+ $this->logger->warning(
+ $msg,
+ $context + [ 'exception' => $e ]
+ );
+ $this->errors[] = self::formatExceptionNoComment( $e );
+ }
+
/**
* Helper method to get and combine versions of multiple modules.
*
return '';
}
$hashes = array_map( function ( $module ) use ( $context ) {
- return $this->getModule( $module )->getVersionHash( $context );
+ try {
+ return $this->getModule( $module )->getVersionHash( $context );
+ } catch ( Exception $e ) {
+ // If modules fail to compute a version, do still consider the versions
+ // of other modules - don't set an empty string E-Tag for the whole request.
+ // See also T152266 and StartupModule::getModuleRegistrations().
+ $this->outputErrorAndLog( $e,
+ 'Calculating version for "{module}" failed: {exception}',
+ [
+ 'module' => $module,
+ ]
+ );
+ return '';
+ }
}, $moduleNames );
return self::makeHash( implode( '', $hashes ) );
}
$module = $this->getModule( $name );
if ( $module ) {
// Do not allow private modules to be loaded from the web.
- // This is a security issue, see bug 34907.
+ // This is a security issue, see T36907.
if ( $module->getGroup() === 'private' ) {
$this->logger->debug( "Request for private module '$name' denied" );
$this->errors[] = "Cannot show private module \"$name\"";
// Preload for getCombinedVersion() and for batch makeModuleResponse()
$this->preloadModuleInfo( array_keys( $modules ), $context );
} catch ( Exception $e ) {
- MWExceptionHandler::logException( $e );
- $this->logger->warning( 'Preloading module info failed: {exception}', [
- 'exception' => $e
- ] );
- $this->errors[] = self::formatExceptionNoComment( $e );
+ $this->outputErrorAndLog( $e, 'Preloading module info failed: {exception}' );
}
// Combine versions to propagate cache invalidation
try {
$versionHash = $this->getCombinedVersion( $context, array_keys( $modules ) );
} catch ( Exception $e ) {
- MWExceptionHandler::logException( $e );
- $this->logger->warning( 'Calculating version hash failed: {exception}', [
- 'exception' => $e
- ] );
- $this->errors[] = self::formatExceptionNoComment( $e );
+ $this->outputErrorAndLog( $e, 'Calculating version hash failed: {exception}' );
}
// See RFC 2616 ยง 3.11 Entity Tags
* @return void
*/
protected function sendResponseHeaders( ResourceLoaderContext $context, $etag, $errors ) {
+ \MediaWiki\HeaderCallback::warnIfHeadersSent();
$rlMaxage = $this->config->get( 'ResourceLoaderMaxage' );
// Use a short cache expiry so that updates propagate to clients quickly, if:
// - No version specified (shared resources, e.g. stylesheets)
return MWExceptionHandler::getPublicLogMessage( $e );
}
- return MWExceptionHandler::getLogMessage( $e );
+ return MWExceptionHandler::getLogMessage( $e ) .
+ "\nBacktrace:\n" .
+ MWExceptionHandler::getRedactedTraceAsString( $e );
}
/**
$out .= $strContent;
} catch ( Exception $e ) {
- MWExceptionHandler::logException( $e );
- $this->logger->warning( 'Generating module package failed: {exception}', [
- 'exception' => $e
- ] );
- $this->errors[] = self::formatExceptionNoComment( $e );
+ $this->outputErrorAndLog( $e, 'Generating module package failed: {exception}' );
// Respond to client with error-state instead of module implementation
$states[$name] = 'error';
$styles = (array)$styles;
foreach ( $styles as $style ) {
$style = trim( $style );
- // Don't output an empty "@media print { }" block (bug 40498)
+ // Don't output an empty "@media print { }" block (T42498)
if ( $style !== '' ) {
// Transform the media type based on request params and config
// The way that this relies on $wgRequest to propagate request params is slightly evil
*/
public function getLessCompiler( $extraVars = [] ) {
// When called from the installer, it is possible that a required PHP extension
- // is missing (at least for now; see bug 47564). If this is the case, throw an
+ // is missing (at least for now; see T49564). If this is the case, throw an
// exception (caught by the installer) to prevent a fatal error later on.
if ( !class_exists( 'Less_Parser' ) ) {
throw new MWException( 'MediaWiki requires the less.php parser' );