exception: Inject wgShowExceptionDetails from Setup.php

Follows-up I8520d8cb16 and Ib941c22d6b7ec5f1b9, and adds an internal
setter for use by Setup.php, and for wmf-config:rpc/RunSingleJob.php
which is a use case for setting it after Setup.php but before most
code execution. Interact with a component owner instead of directly
maintaining state and providing a shared API through the Config object.

Change-Id: I5c3d4b11f4e0eb3906ccb5b5fe3979e026459859
This commit is contained in:
Timo Tijhof 2022-05-19 13:57:14 +01:00 committed by Krinkle
parent 31145ce2ff
commit 30fe871e82
7 changed files with 38 additions and 49 deletions

View file

@ -12,6 +12,7 @@ use MediaWiki\Rest\BasicAccess\CompoundAuthorizer;
use MediaWiki\Rest\BasicAccess\MWBasicAuthorizer;
use MediaWiki\Rest\Reporter\MWErrorReporter;
use MediaWiki\Rest\Validator\Validator;
use MWExceptionRenderer;
use RequestContext;
use Title;
use WebResponse;
@ -110,7 +111,7 @@ class EntryPoint {
$conf = $services->getMainConfig();
$responseFactory = new ResponseFactory( self::getTextFormatters( $services ) );
$responseFactory->setSendExceptionBacktrace( $conf->get( 'ShowExceptionDetails' ) );
$responseFactory->setSendExceptionBacktrace( MWExceptionRenderer::shouldShowExceptionDetails() );
$cors = new CorsUtils(
new ServiceOptions(

View file

@ -290,6 +290,7 @@ MediaWikiServices::allowGlobalInstance();
// is complete.
define( 'MW_SERVICE_BOOTSTRAP_COMPLETE', 1 );
MWExceptionRenderer::setShowExceptionDetails( $wgShowExceptionDetails );
MWExceptionHandler::installHandler( $wgLogExceptionBacktrace, $wgPropagateErrors );
// Non-trivial validation of: $wgServer

View file

@ -1304,13 +1304,11 @@ class ApiMain extends ApiBase {
} elseif ( $type !== 'error' ) {
// None of the rest have any messages for non-error types
} else {
// Something is seriously wrong
$config = $this->getConfig();
// TODO: Avoid embedding arbitrary class names in the error code.
$class = preg_replace( '#^Wikimedia\\\Rdbms\\\#', '', get_class( $e ) );
$code = 'internal_api_error_' . $class;
$data = [ 'errorclass' => get_class( $e ) ];
if ( $config->get( MainConfigNames::ShowExceptionDetails ) ) {
if ( MWExceptionRenderer::shouldShowExceptionDetails() ) {
if ( $e instanceof ILocalizedException ) {
$msg = $e->getMessageObject();
} elseif ( $e instanceof MessageSpecifier ) {

View file

@ -17,8 +17,6 @@
*
* @file
*/
use MediaWiki\MainConfigNames;
use MediaWiki\MediaWikiServices;
/**
* MediaWiki exception
@ -101,29 +99,16 @@ class MWException extends Exception {
return $res;
}
private function shouldShowExceptionDetails(): bool {
// NOTE: keep in sync with MWExceptionRenderer::shouldShowExceptionDetails
if ( MediaWikiServices::hasInstance() ) {
$services = MediaWikiServices::getInstance();
if ( $services->hasService( 'MainConfig' ) ) {
return $services->getMainConfig()->get( MainConfigNames::ShowExceptionDetails );
}
}
global $wgShowExceptionDetails;
return $wgShowExceptionDetails ?? false;
}
/**
* If $wgShowExceptionDetails is true, return a HTML message with a
* backtrace to the error, otherwise show a message to ask to set it to true
* to show that information.
* Format an HTML message for the current exception object.
*
*
* @stable to override
*
* @return string Html to output
* @todo Rarely used, remove in favour of generic MWExceptionRenderer
* @return string HTML to output
*/
public function getHTML() {
if ( self::shouldShowExceptionDetails() ) {
if ( MWExceptionRenderer::shouldShowExceptionDetails() ) {
return '<p>' . nl2br( htmlspecialchars( MWExceptionHandler::getLogMessage( $this ) ) ) .
'</p><p>Backtrace:</p><p>' .
nl2br( htmlspecialchars( MWExceptionHandler::getRedactedTraceAsString( $this ) ) ) .
@ -149,16 +134,14 @@ class MWException extends Exception {
}
/**
* Get the text to display when reporting the error on the command line.
* If $wgShowExceptionDetails is true, return a text message with a
* backtrace to the error.
* Format plain text message for the current exception object.
*
* @stable to override
*
* @todo Rarely used, remove in favour of generic MWExceptionRenderer
* @return string
*/
public function getText() {
if ( self::shouldShowExceptionDetails() ) {
if ( MWExceptionRenderer::shouldShowExceptionDetails() ) {
return MWExceptionHandler::getLogMessage( $this ) .
"\nBacktrace:\n" . MWExceptionHandler::getRedactedTraceAsString( $this ) . "\n";
} else {

View file

@ -34,19 +34,30 @@ class MWExceptionRenderer {
public const AS_RAW = 1; // show as text
public const AS_PRETTY = 2; // show as HTML
private static function shouldShowExceptionDetails(): bool {
// NOTE: keep in sync with MWException::shouldShowExceptionDetails
if ( MediaWikiServices::hasInstance() ) {
$services = MediaWikiServices::getInstance();
if ( $services->hasService( 'MainConfig' ) ) {
return $services->getMainConfig()->get( MainConfigNames::ShowExceptionDetails );
}
}
/**
* Whether to print exceptino details.
*
* The default is configured by $wgShowExceptionDetails.
* May be changed at runtime via MWExceptionRenderer::setShowExceptionDetails().
*
* @see MainConfigNames::ShowExceptionDetails
*/
private static $showExceptionDetails = false;
// Shouldn't happen, since Setup.php calls MediaWikiServices::allowGlobalInstance() before
// MWExceptionHandler::installHandler(). But we shouldn't just crash and if it does,
// we should return nicely and continue to report the original error.
return false;
/**
* @internal For use within core wiring only.
* @return bool
*/
public static function shouldShowExceptionDetails(): bool {
return self::$showExceptionDetails;
}
/**
* @param bool $showDetails
* @internal For use by Setup.php and other internal use cases.
*/
public static function setShowExceptionDetails( bool $showDetails ): void {
self::$showExceptionDetails = $showDetails;
}
/**
@ -189,15 +200,12 @@ class MWExceptionRenderer {
}
/**
* If $wgShowExceptionDetails is true, return a HTML message with a
* backtrace to the error, otherwise show a message to ask to set it to true
* to show that information.
* Format an HTML message for the given exception object.
*
* @param Throwable $e
* @return string Html to output
*/
public static function getHTML( Throwable $e ) {
// XXX: do we need a parameter to control inclusion of exception details?
if ( self::shouldShowExceptionDetails() ) {
$html = Html::errorBox( "<p>" .
nl2br( htmlspecialchars( MWExceptionHandler::getLogMessage( $e ) ) ) .

View file

@ -425,6 +425,7 @@ abstract class DatabaseInstaller {
$up->doUpdates();
$up->purgeCache();
} catch ( MWException $e ) {
// TODO: Remove special casing in favour of MWExceptionRenderer
echo "\nAn error occurred:\n";
echo $e->getText();
$ret = false;

View file

@ -1014,10 +1014,7 @@ class ResourceLoader implements LoggerAwareInterface {
* @return string Sanitized text that can be returned to the user
*/
protected static function formatExceptionNoComment( Throwable $e ) {
$showExceptionDetails = MediaWikiServices::getInstance()->getMainConfig()->get(
MainConfigNames::ShowExceptionDetails );
if ( !$showExceptionDetails ) {
if ( !MWExceptionRenderer::shouldShowExceptionDetails() ) {
return MWExceptionHandler::getPublicLogMessage( $e );
}