From f9c7383de9e19c95e41fa4e136fd8c02c29781a7 Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Mon, 20 Apr 2015 12:09:24 -0400 Subject: [PATCH] API: Better handle UsageException from the printer itself Try falling back to use the printer without any of its parameters in case one of them is what's failing. Change-Id: I2611550109de4219bf1cc43333d038753e9eb87c --- includes/api/ApiFormatBase.php | 29 ++++++++++++++++++++++++ includes/api/ApiMain.php | 41 ++++++++++++++++++++++------------ 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/includes/api/ApiFormatBase.php b/includes/api/ApiFormatBase.php index 26eac082fa..d078dc453f 100644 --- a/includes/api/ApiFormatBase.php +++ b/includes/api/ApiFormatBase.php @@ -32,6 +32,7 @@ abstract class ApiFormatBase extends ApiBase { private $mIsHtml, $mFormat, $mUnescapeAmps, $mHelp; private $mBuffer, $mDisabled = false; + protected $mForceDefaultParams = false; /** * If $format ends with 'fm', pretty-print the output in HTML. @@ -107,6 +108,34 @@ abstract class ApiFormatBase extends ApiBase { return true; } + /** + * Ignore request parameters, force a default. + * + * Used as a fallback if errors are being thrown. + * @since 1.26 + */ + public function forceDefaultParams() { + $this->mForceDefaultParams = true; + } + + /** + * Overridden to honor $this->forceDefaultParams(), if applicable + * @since 1.26 + */ + protected function getParameterFromSettings( $paramName, $paramSettings, $parseLimit ) { + if ( !$this->mForceDefaultParams ) { + return parent::getParameterFromSettings( $paramName, $paramSettings, $parseLimit ); + } + + if ( !is_array( $paramSettings ) ) { + return $paramSettings; + } elseif ( isset( $paramSettings[self::PARAM_DFLT] ) ) { + return $paramSettings[self::PARAM_DFLT]; + } else { + return null; + } + } + /** * Initialize the printer function and prepare the output headers. * @param bool $unused Always false since 1.25 diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php index 7e3dcff2ee..2ec3aa8675 100644 --- a/includes/api/ApiMain.php +++ b/includes/api/ApiMain.php @@ -495,7 +495,22 @@ class ApiMain extends ApiBase { // Reset and print just the error message ob_clean(); - $this->printResult( true ); + // Printer may not be initialized if the extractRequestParams() fails for the main module + $this->createErrorPrinter(); + + try { + $this->printResult( true ); + } catch ( UsageException $ex ) { + // The error printer itself is failing. Try suppressing its request + // parameters and redo. + $this->setWarning( + 'Error printer failed (will retry without params): ' . $ex->getMessage() + ); + $this->mPrinter = null; + $this->createErrorPrinter(); + $this->mPrinter->forceDefaultParams(); + $this->printResult( true ); + } } /** @@ -792,22 +807,14 @@ class ApiMain extends ApiBase { } /** - * Replace the result data with the information about an exception. - * Returns the error code - * @param Exception $e - * @return string + * Create the printer for error output */ - protected function substituteResultWithError( $e ) { - $result = $this->getResult(); - - // Printer may not be initialized if the extractRequestParams() fails for the main module + private function createErrorPrinter() { if ( !isset( $this->mPrinter ) ) { - // The printer has not been created yet. Try to manually get formatter value. $value = $this->getRequest()->getVal( 'format', self::API_DEFAULT_FORMAT ); if ( !$this->mModuleMgr->isDefined( $value, 'format' ) ) { $value = self::API_DEFAULT_FORMAT; } - $this->mPrinter = $this->createPrinterByName( $value ); } @@ -816,10 +823,16 @@ class ApiMain extends ApiBase { if ( !$this->mPrinter->canPrintErrors() ) { $this->mPrinter = $this->createPrinterByName( self::API_DEFAULT_FORMAT ); } + } - // Update raw mode flag for the selected printer. - $result->setRawMode( $this->mPrinter->getNeedsRawData() ); - + /** + * Replace the result data with the information about an exception. + * Returns the error code + * @param Exception $e + * @return string + */ + protected function substituteResultWithError( $e ) { + $result = $this->getResult(); $config = $this->getConfig(); if ( $e instanceof UsageException ) { -- 2.20.1