* @author Trevor Parscal
*/
+use MediaWiki\MediaWikiServices;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
if ( !$config ) {
$this->logger->debug( __METHOD__ . ' was called without providing a Config instance' );
- $config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' );
+ $config = MediaWikiServices::getInstance()->getMainConfig();
}
$this->config = $config;
}
}
- /**
- */
public function registerTestModules() {
global $IP;
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 ) );
}
// 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 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';