From 6ff65e57bbf203a53a2f0232f76d55116e85d928 Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Wed, 10 Oct 2018 13:55:09 -0400 Subject: [PATCH] API: Remove long-deprecated methods (and one class) * ApiBase::profileIn() (deprecated in 1.25) * ApiBase::profileOut() (deprecated in 1.25) * ApiBase::safeProfileOut() (deprecated in 1.25) * ApiBase::profileDBIn() (deprecated in 1.25) * ApiBase::profileDBOut() (deprecated in 1.25) * ApiBase::dieUsage() (deprecated in 1.29) * ApiBase::dieUsageMsg() (deprecated in 1.29) * ApiBase::dieUsageMsgOrDebug() (deprecated in 1.29) * ApiBase::getErrorFromStatus() (deprecated in 1.29) * ApiBase::parseMsg() (deprecated in 1.29) * ApiBase::setWarning() (deprecated in 1.29) * ApiPageSet::getInvalidTitles() (deprecated in 1.26) * ApiQueryLogEvents::addLogParams() (deprecated in 1.25) * ApiUsageException::getCodeString() (deprecated in 1.29) * ApiUsageException::getMessageArray() (deprecated in 1.29) * UsageException (deprecated in 1.29) Change-Id: Iabb2589a29cc3b46624d31358f3a6bf7b3ccbd57 --- RELEASE-NOTES-1.32 | 34 ++ autoload.php | 1 - includes/api/ApiBase.php | 356 +----------------- includes/api/ApiErrorFormatter.php | 10 - includes/api/ApiFeedWatchlist.php | 8 +- includes/api/ApiMain.php | 23 +- includes/api/ApiPageSet.php | 13 - includes/api/ApiQueryImageInfo.php | 5 +- includes/api/ApiQueryLogEvents.php | 26 -- includes/api/ApiUsageException.php | 39 +- includes/api/UsageException.php | 90 ----- includes/api/i18n/en.json | 2 +- includes/api/i18n/qqq.json | 2 +- includes/specials/SpecialApiHelp.php | 5 - .../includes/api/ApiErrorFormatterTest.php | 32 -- tests/phpunit/includes/api/ApiMainTest.php | 21 -- 16 files changed, 56 insertions(+), 611 deletions(-) delete mode 100644 includes/api/UsageException.php diff --git a/RELEASE-NOTES-1.32 b/RELEASE-NOTES-1.32 index a63a16d293..4ae590d215 100644 --- a/RELEASE-NOTES-1.32 +++ b/RELEASE-NOTES-1.32 @@ -191,6 +191,23 @@ production. * ApiFeedContributions::feedItemAuthor() * ApiFeedContributions::feedItemDesc() * ApiQueryRevisionsBase::extractRevisionInfo() +* The following deprecated methods have been removed: + * ApiBase::profileIn() (deprecated in 1.25) + * ApiBase::profileOut() (deprecated in 1.25) + * ApiBase::safeProfileOut() (deprecated in 1.25) + * ApiBase::profileDBIn() (deprecated in 1.25) + * ApiBase::profileDBOut() (deprecated in 1.25) + * ApiBase::dieUsage() (deprecated in 1.29) + * ApiBase::dieUsageMsg() (deprecated in 1.29) + * ApiBase::dieUsageMsgOrDebug() (deprecated in 1.29) + * ApiBase::getErrorFromStatus() (deprecated in 1.29) + * ApiBase::parseMsg() (deprecated in 1.29) + * ApiBase::setWarning() (deprecated in 1.29) + * ApiPageSet::getInvalidTitles() (deprecated in 1.26) + * ApiQueryLogEvents::addLogParams() (deprecated in 1.25) + * ApiUsageException::getCodeString() (deprecated in 1.29) + * ApiUsageException::getMessageArray() (deprecated in 1.29) +* Class UsageException, deprecated in 1.29, has been removed. === Languages updated in 1.32 === MediaWiki supports over 350 languages. Many localisations are updated regularly. @@ -358,6 +375,23 @@ because of Phabricator reports. * The hook 'UnknownAction', deprecated since 1.19, has now been removed. * The hook 'ParserLimitReport', deprecated since 1.22, has been removed. Use the hooks 'ParserLimitReportPrepare' and 'ParserLimitReportFormat' instead. +* The following deprecated API methods have been removed: + * ApiBase::profileIn() (deprecated in 1.25) + * ApiBase::profileOut() (deprecated in 1.25) + * ApiBase::safeProfileOut() (deprecated in 1.25) + * ApiBase::profileDBIn() (deprecated in 1.25) + * ApiBase::profileDBOut() (deprecated in 1.25) + * ApiBase::dieUsage() (deprecated in 1.29) + * ApiBase::dieUsageMsg() (deprecated in 1.29) + * ApiBase::dieUsageMsgOrDebug() (deprecated in 1.29) + * ApiBase::getErrorFromStatus() (deprecated in 1.29) + * ApiBase::parseMsg() (deprecated in 1.29) + * ApiBase::setWarning() (deprecated in 1.29) + * ApiPageSet::getInvalidTitles() (deprecated in 1.26) + * ApiQueryLogEvents::addLogParams() (deprecated in 1.25) + * ApiUsageException::getCodeString() (deprecated in 1.29) + * ApiUsageException::getMessageArray() (deprecated in 1.29) +* Class UsageException, deprecated in 1.29, has been removed. === Deprecations in 1.32 === * HTMLForm::setSubmitProgressive() is deprecated. No need to call it. Submit diff --git a/autoload.php b/autoload.php index 0f92ccbde0..3e6b4a20b7 100644 --- a/autoload.php +++ b/autoload.php @@ -1536,7 +1536,6 @@ $wgAutoloadLocalClasses = [ 'UploadStashWrongOwnerException' => __DIR__ . '/includes/upload/UploadStash.php', 'UploadStashZeroLengthFileException' => __DIR__ . '/includes/upload/UploadStash.php', 'UppercaseCollation' => __DIR__ . '/includes/collation/UppercaseCollation.php', - 'UsageException' => __DIR__ . '/includes/api/UsageException.php', 'User' => __DIR__ . '/includes/user/User.php', 'UserArray' => __DIR__ . '/includes/user/UserArray.php', 'UserArrayFromResult' => __DIR__ . '/includes/user/UserArrayFromResult.php', diff --git a/includes/api/ApiBase.php b/includes/api/ApiBase.php index c2e37e0161..bb86536cb3 100644 --- a/includes/api/ApiBase.php +++ b/includes/api/ApiBase.php @@ -1872,6 +1872,16 @@ abstract class ApiBase extends ContextSource { return $status; } + /** + * Call wfTransactionalTimeLimit() if this request was POSTed + * @since 1.26 + */ + protected function useTransactionalTimeLimit() { + if ( $this->getRequest()->wasPosted() ) { + wfTransactionalTimeLimit(); + } + } + /**@}*/ /************************************************************************//** @@ -2671,352 +2681,6 @@ abstract class ApiBase extends ContextSource { return false; } - /** - * @deprecated since 1.25 - */ - public function profileIn() { - wfDeprecated( __METHOD__, '1.25' ); - } - - /** - * @deprecated since 1.25 - */ - public function profileOut() { - wfDeprecated( __METHOD__, '1.25' ); - } - - /** - * @deprecated since 1.25 - */ - public function safeProfileOut() { - wfDeprecated( __METHOD__, '1.25' ); - } - - /** - * @deprecated since 1.25 - */ - public function profileDBIn() { - wfDeprecated( __METHOD__, '1.25' ); - } - - /** - * @deprecated since 1.25 - */ - public function profileDBOut() { - wfDeprecated( __METHOD__, '1.25' ); - } - - /** - * Call wfTransactionalTimeLimit() if this request was POSTed - * @since 1.26 - */ - protected function useTransactionalTimeLimit() { - if ( $this->getRequest()->wasPosted() ) { - wfTransactionalTimeLimit(); - } - } - - /** - * @deprecated since 1.29, use ApiBase::addWarning() instead - * @param string $warning Warning message - */ - public function setWarning( $warning ) { - wfDeprecated( __METHOD__, '1.29' ); - $msg = new ApiRawMessage( $warning, 'warning' ); - $this->getErrorFormatter()->addWarning( $this->getModulePath(), $msg ); - } - - /** - * Throw an ApiUsageException, which will (if uncaught) call the main module's - * error handler and die with an error message. - * - * @deprecated since 1.29, use self::dieWithError() instead - * @param string $description One-line human-readable description of the - * error condition, e.g., "The API requires a valid action parameter" - * @param string $errorCode Brief, arbitrary, stable string to allow easy - * automated identification of the error, e.g., 'unknown_action' - * @param int $httpRespCode HTTP response code - * @param array|null $extradata Data to add to the "" element; array in ApiResult format - * @throws ApiUsageException always - */ - public function dieUsage( $description, $errorCode, $httpRespCode = 0, $extradata = null ) { - wfDeprecated( __METHOD__, '1.29' ); - $this->dieWithError( - new RawMessage( '$1', [ $description ] ), - $errorCode, - $extradata, - $httpRespCode - ); - } - - /** - * Get error (as code, string) from a Status object. - * - * @since 1.23 - * @deprecated since 1.29, use ApiErrorFormatter::arrayFromStatus instead - * @param Status $status - * @param array|null &$extraData Set if extra data from IApiMessage is available (since 1.27) - * @return array Array of code and error string - * @throws MWException - */ - public function getErrorFromStatus( $status, &$extraData = null ) { - wfDeprecated( __METHOD__, '1.29' ); - if ( $status->isGood() ) { - throw new MWException( 'Successful status passed to ApiBase::dieStatus' ); - } - - $errors = $status->getErrorsByType( 'error' ); - if ( !$errors ) { - // No errors? Assume the warnings should be treated as errors - $errors = $status->getErrorsByType( 'warning' ); - } - if ( !$errors ) { - // Still no errors? Punt - $errors = [ [ 'message' => 'unknownerror-nocode', 'params' => [] ] ]; - } - - if ( $errors[0]['message'] instanceof MessageSpecifier ) { - $msg = $errors[0]['message']; - } else { - $msg = new Message( $errors[0]['message'], $errors[0]['params'] ); - } - if ( !$msg instanceof IApiMessage ) { - $key = $msg->getKey(); - $params = $msg->getParams(); - array_unshift( $params, self::$messageMap[$key] ?? $key ); - $msg = ApiMessage::create( $params ); - } - - return [ - $msg->getApiCode(), - ApiErrorFormatter::stripMarkup( $msg->inLanguage( 'en' )->useDatabase( false )->text() ) - ]; - } - - /** - * @deprecated since 1.29. Prior to 1.29, this was a public mapping from - * arbitrary strings (often message keys used elsewhere in MediaWiki) to - * API codes and message texts, and a few interfaces required poking - * something in here. Now we're repurposing it to map those same strings - * to i18n messages, and declaring that any interface that requires poking - * at this is broken and needs replacing ASAP. - */ - private static $messageMap = [ - 'unknownerror' => 'apierror-unknownerror', - 'unknownerror-nocode' => 'apierror-unknownerror-nocode', - 'ns-specialprotected' => 'ns-specialprotected', - 'protectedinterface' => 'protectedinterface', - 'namespaceprotected' => 'namespaceprotected', - 'customcssprotected' => 'customcssprotected', - 'customjsprotected' => 'customjsprotected', - 'cascadeprotected' => 'cascadeprotected', - 'protectedpagetext' => 'protectedpagetext', - 'protect-cantedit' => 'protect-cantedit', - 'deleteprotected' => 'deleteprotected', - 'badaccess-group0' => 'badaccess-group0', - 'badaccess-groups' => 'badaccess-groups', - 'titleprotected' => 'titleprotected', - 'nocreate-loggedin' => 'nocreate-loggedin', - 'nocreatetext' => 'nocreatetext', - 'movenologintext' => 'movenologintext', - 'movenotallowed' => 'movenotallowed', - 'confirmedittext' => 'confirmedittext', - 'blockedtext' => 'apierror-blocked', - 'autoblockedtext' => 'apierror-autoblocked', - 'systemblockedtext' => 'apierror-systemblocked', - 'actionthrottledtext' => 'apierror-ratelimited', - 'alreadyrolled' => 'alreadyrolled', - 'cantrollback' => 'cantrollback', - 'readonlytext' => 'readonlytext', - 'sessionfailure' => 'sessionfailure', - 'cannotdelete' => 'cannotdelete', - 'notanarticle' => 'apierror-missingtitle', - 'selfmove' => 'selfmove', - 'immobile_namespace' => 'apierror-immobilenamespace', - 'articleexists' => 'articleexists', - 'hookaborted' => 'hookaborted', - 'cantmove-titleprotected' => 'cantmove-titleprotected', - 'imagenocrossnamespace' => 'imagenocrossnamespace', - 'imagetypemismatch' => 'imagetypemismatch', - 'ip_range_invalid' => 'ip_range_invalid', - 'range_block_disabled' => 'range_block_disabled', - 'nosuchusershort' => 'nosuchusershort', - 'badipaddress' => 'badipaddress', - 'ipb_expiry_invalid' => 'ipb_expiry_invalid', - 'ipb_already_blocked' => 'ipb_already_blocked', - 'ipb_blocked_as_range' => 'ipb_blocked_as_range', - 'ipb_cant_unblock' => 'ipb_cant_unblock', - 'mailnologin' => 'apierror-cantsend', - 'ipbblocked' => 'ipbblocked', - 'ipbnounblockself' => 'ipbnounblockself', - 'usermaildisabled' => 'usermaildisabled', - 'blockedemailuser' => 'apierror-blockedfrommail', - 'notarget' => 'apierror-notarget', - 'noemail' => 'noemail', - 'rcpatroldisabled' => 'rcpatroldisabled', - 'markedaspatrollederror-noautopatrol' => 'markedaspatrollederror-noautopatrol', - 'delete-toobig' => 'delete-toobig', - 'movenotallowedfile' => 'movenotallowedfile', - 'userrights-no-interwiki' => 'userrights-no-interwiki', - 'userrights-nodatabase' => 'userrights-nodatabase', - 'nouserspecified' => 'nouserspecified', - 'noname' => 'noname', - 'summaryrequired' => 'apierror-summaryrequired', - 'import-rootpage-invalid' => 'import-rootpage-invalid', - 'import-rootpage-nosubpage' => 'import-rootpage-nosubpage', - 'readrequired' => 'apierror-readapidenied', - 'writedisabled' => 'apierror-noapiwrite', - 'writerequired' => 'apierror-writeapidenied', - 'missingparam' => 'apierror-missingparam', - 'invalidtitle' => 'apierror-invalidtitle', - 'nosuchpageid' => 'apierror-nosuchpageid', - 'nosuchrevid' => 'apierror-nosuchrevid', - 'nosuchuser' => 'nosuchusershort', - 'invaliduser' => 'apierror-invaliduser', - 'invalidexpiry' => 'apierror-invalidexpiry', - 'pastexpiry' => 'apierror-pastexpiry', - 'create-titleexists' => 'apierror-create-titleexists', - 'missingtitle-createonly' => 'apierror-missingtitle-createonly', - 'cantblock' => 'apierror-cantblock', - 'canthide' => 'apierror-canthide', - 'cantblock-email' => 'apierror-cantblock-email', - 'cantunblock' => 'apierror-permissiondenied-generic', - 'cannotundelete' => 'cannotundelete', - 'permdenied-undelete' => 'apierror-permissiondenied-generic', - 'createonly-exists' => 'apierror-articleexists', - 'nocreate-missing' => 'apierror-missingtitle', - 'cantchangecontentmodel' => 'apierror-cantchangecontentmodel', - 'nosuchrcid' => 'apierror-nosuchrcid', - 'nosuchlogid' => 'apierror-nosuchlogid', - 'protect-invalidaction' => 'apierror-protect-invalidaction', - 'protect-invalidlevel' => 'apierror-protect-invalidlevel', - 'toofewexpiries' => 'apierror-toofewexpiries', - 'cantimport' => 'apierror-cantimport', - 'cantimport-upload' => 'apierror-cantimport-upload', - 'importnofile' => 'importnofile', - 'importuploaderrorsize' => 'importuploaderrorsize', - 'importuploaderrorpartial' => 'importuploaderrorpartial', - 'importuploaderrortemp' => 'importuploaderrortemp', - 'importcantopen' => 'importcantopen', - 'import-noarticle' => 'import-noarticle', - 'importbadinterwiki' => 'importbadinterwiki', - 'import-unknownerror' => 'apierror-import-unknownerror', - 'cantoverwrite-sharedfile' => 'apierror-cantoverwrite-sharedfile', - 'sharedfile-exists' => 'apierror-fileexists-sharedrepo-perm', - 'mustbeposted' => 'apierror-mustbeposted', - 'show' => 'apierror-show', - 'specialpage-cantexecute' => 'apierror-specialpage-cantexecute', - 'invalidoldimage' => 'apierror-invalidoldimage', - 'nodeleteablefile' => 'apierror-nodeleteablefile', - 'fileexists-forbidden' => 'fileexists-forbidden', - 'fileexists-shared-forbidden' => 'fileexists-shared-forbidden', - 'filerevert-badversion' => 'filerevert-badversion', - 'noimageredirect-anon' => 'apierror-noimageredirect-anon', - 'noimageredirect-logged' => 'apierror-noimageredirect', - 'spamdetected' => 'apierror-spamdetected', - 'contenttoobig' => 'apierror-contenttoobig', - 'noedit-anon' => 'apierror-noedit-anon', - 'noedit' => 'apierror-noedit', - 'wasdeleted' => 'apierror-pagedeleted', - 'blankpage' => 'apierror-emptypage', - 'editconflict' => 'editconflict', - 'hashcheckfailed' => 'apierror-badmd5', - 'missingtext' => 'apierror-notext', - 'emptynewsection' => 'apierror-emptynewsection', - 'revwrongpage' => 'apierror-revwrongpage', - 'undo-failure' => 'undo-failure', - 'content-not-allowed-here' => 'content-not-allowed-here', - 'edit-hook-aborted' => 'edit-hook-aborted', - 'edit-gone-missing' => 'edit-gone-missing', - 'edit-conflict' => 'edit-conflict', - 'edit-already-exists' => 'edit-already-exists', - 'invalid-file-key' => 'apierror-invalid-file-key', - 'nouploadmodule' => 'apierror-nouploadmodule', - 'uploaddisabled' => 'uploaddisabled', - 'copyuploaddisabled' => 'copyuploaddisabled', - 'copyuploadbaddomain' => 'apierror-copyuploadbaddomain', - 'copyuploadbadurl' => 'apierror-copyuploadbadurl', - 'filename-tooshort' => 'filename-tooshort', - 'filename-toolong' => 'filename-toolong', - 'illegal-filename' => 'illegal-filename', - 'filetype-missing' => 'filetype-missing', - 'mustbeloggedin' => 'apierror-mustbeloggedin', - ]; - - /** - * @deprecated do not use - * @param array|string|MessageSpecifier $error Element of a getUserPermissionsErrors()-style array - * @return ApiMessage - */ - private function parseMsgInternal( $error ) { - $msg = Message::newFromSpecifier( $error ); - if ( !$msg instanceof IApiMessage ) { - $key = $msg->getKey(); - if ( isset( self::$messageMap[$key] ) ) { - $params = $msg->getParams(); - array_unshift( $params, self::$messageMap[$key] ); - } else { - $params = [ 'apierror-unknownerror', wfEscapeWikiText( $key ) ]; - } - $msg = ApiMessage::create( $params ); - } - return $msg; - } - - /** - * Return the error message related to a certain array - * @deprecated since 1.29 - * @param array|string|MessageSpecifier $error Element of a getUserPermissionsErrors()-style array - * @return array [ 'code' => code, 'info' => info ] - */ - public function parseMsg( $error ) { - wfDeprecated( __METHOD__, '1.29' ); - // Check whether someone passed the whole array, instead of one element as - // documented. This breaks if it's actually an array of fallback keys, but - // that's long-standing misbehavior introduced in r87627 to incorrectly - // fix T30797. - if ( is_array( $error ) ) { - $first = reset( $error ); - if ( is_array( $first ) ) { - wfDebug( __METHOD__ . ' was passed an array of arrays. ' . wfGetAllCallers( 5 ) ); - $error = $first; - } - } - - $msg = $this->parseMsgInternal( $error ); - return [ - 'code' => $msg->getApiCode(), - 'info' => ApiErrorFormatter::stripMarkup( - $msg->inLanguage( 'en' )->useDatabase( false )->text() - ), - 'data' => $msg->getApiData() - ]; - } - - /** - * Output the error message related to a certain array - * @deprecated since 1.29, use ApiBase::dieWithError() instead - * @param array|string|MessageSpecifier $error Element of a getUserPermissionsErrors()-style array - * @throws ApiUsageException always - */ - public function dieUsageMsg( $error ) { - wfDeprecated( __METHOD__, '1.29' ); - $this->dieWithError( $this->parseMsgInternal( $error ) ); - } - - /** - * Will only set a warning instead of failing if the global $wgDebugAPI - * is set to true. Otherwise behaves exactly as dieUsageMsg(). - * @deprecated since 1.29, use ApiBase::dieWithErrorOrDebug() instead - * @param array|string|MessageSpecifier $error Element of a getUserPermissionsErrors()-style array - * @throws ApiUsageException - * @since 1.21 - */ - public function dieUsageMsgOrDebug( $error ) { - wfDeprecated( __METHOD__, '1.29' ); - $this->dieWithErrorOrDebug( $this->parseMsgInternal( $error ) ); - } - /** * Return the description message. * diff --git a/includes/api/ApiErrorFormatter.php b/includes/api/ApiErrorFormatter.php index af23f95f5c..5a52c5f143 100644 --- a/includes/api/ApiErrorFormatter.php +++ b/includes/api/ApiErrorFormatter.php @@ -164,16 +164,6 @@ class ApiErrorFormatter { $msg = Message::newFromSpecifier( $exception ); $params = []; } else { - // Extract code and data from the exception, if applicable - if ( $exception instanceof UsageException ) { - $data = $exception->getMessageArray(); - if ( !$options['code'] ) { - $options['code'] = $data['code']; - } - unset( $data['code'], $data['info'] ); - $options['data'] = array_merge( $data, $options['data'] ); - } - if ( isset( $options['wrap'] ) ) { $msg = $options['wrap']; } else { diff --git a/includes/api/ApiFeedWatchlist.php b/includes/api/ApiFeedWatchlist.php index c21ac12e82..37ec3cfd32 100644 --- a/includes/api/ApiFeedWatchlist.php +++ b/includes/api/ApiFeedWatchlist.php @@ -157,12 +157,8 @@ class ApiFeedWatchlist extends ApiBase { $feedItems[] = new FeedItem( $errorTitle, $errorText, '', '', '' ); } } else { - if ( $e instanceof UsageException ) { - $errorCode = $e->getCodeString(); - } else { - // Something is seriously wrong - $errorCode = 'internal_api_error'; - } + // Something is seriously wrong + $errorCode = 'internal_api_error'; $errorTitle = $this->msg( 'api-feed-error-title', $errorCode ); $errorText = $e->getMessage(); $feedItems[] = new FeedItem( $errorTitle, $errorText, '', '', '' ); diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php index 3b305f9e5c..d2a7db2bea 100644 --- a/includes/api/ApiMain.php +++ b/includes/api/ApiMain.php @@ -566,8 +566,8 @@ class ApiMain extends ApiBase { */ protected function handleException( $e ) { // T65145: Rollback any open database transactions - if ( !( $e instanceof ApiUsageException || $e instanceof UsageException ) ) { - // UsageExceptions are intentional, so don't rollback if that's the case + if ( !$e instanceof ApiUsageException ) { + // ApiUsageExceptions are intentional, so don't rollback if that's the case MWExceptionHandler::rollbackMasterChangesAndLog( $e ); } @@ -612,13 +612,6 @@ class ApiMain extends ApiBase { $this->addWarning( $error ); } } - } catch ( UsageException $ex ) { - // The error printer itself is failing. Try suppressing its request - // parameters and redo. - $failed = true; - $this->addWarning( - [ 'apiwarn-errorprinterfailed-ex', $ex->getMessage() ], 'errorprinterfailed' - ); } if ( $failed ) { $this->mPrinter = null; @@ -1012,9 +1005,6 @@ class ApiMain extends ApiBase { * If an ApiUsageException, errors/warnings will be extracted from the * embedded StatusValue. * - * If a base UsageException, the getMessageArray() method will be used to - * extract the code and English message for a single error (no warnings). - * * Any other exception will be returned with a generic code and wrapper * text around the exception's (presumably English) message as a single * error (no warnings). @@ -1032,13 +1022,6 @@ class ApiMain extends ApiBase { } } elseif ( $type !== 'error' ) { // None of the rest have any messages for non-error types - } elseif ( $e instanceof UsageException ) { - // User entered incorrect parameters - generate error response - $data = Wikimedia\quietCall( [ $e, 'getMessageArray' ] ); - $code = $data['code']; - $info = $data['info']; - unset( $data['code'], $data['info'] ); - $messages[] = new ApiRawMessage( [ '$1', $info ], $code, $data ); } else { // Something is seriously wrong $config = $this->getConfig(); @@ -1108,7 +1091,7 @@ class ApiMain extends ApiBase { } else { $path = null; } - if ( $e instanceof ApiUsageException || $e instanceof UsageException ) { + if ( $e instanceof ApiUsageException ) { $link = wfExpandUrl( wfScript( 'api' ) ); $result->addContentValue( $path, diff --git a/includes/api/ApiPageSet.php b/includes/api/ApiPageSet.php index 26846f4332..194a511061 100644 --- a/includes/api/ApiPageSet.php +++ b/includes/api/ApiPageSet.php @@ -418,19 +418,6 @@ class ApiPageSet extends ApiBase { return $this->mGoodTitles + $this->mMissingTitles; } - /** - * Titles that were deemed invalid by Title::newFromText() - * The array's index will be unique and negative for each item - * @deprecated since 1.26, use self::getInvalidTitlesAndReasons() - * @return string[] Array of strings (not Title objects) - */ - public function getInvalidTitles() { - wfDeprecated( __METHOD__, '1.26' ); - return array_map( function ( $t ) { - return $t['title']; - }, $this->mInvalidTitles ); - } - /** * Titles that were deemed invalid by Title::newFromText() * The array's index will be unique and negative for each item diff --git a/includes/api/ApiQueryImageInfo.php b/includes/api/ApiQueryImageInfo.php index 18d2804c2f..37a7ff33a7 100644 --- a/includes/api/ApiQueryImageInfo.php +++ b/includes/api/ApiQueryImageInfo.php @@ -59,7 +59,8 @@ class ApiQueryImageInfo extends ApiQueryBase { if ( isset( $params['badfilecontexttitle'] ) ) { $badFileContextTitle = Title::newFromText( $params['badfilecontexttitle'] ); if ( !$badFileContextTitle ) { - $this->dieUsage( 'Invalid title in badfilecontexttitle parameter', 'invalid-title' ); + $p = $this->getModulePrefix(); + $this->dieWithError( [ 'apierror-bad-badfilecontexttitle', $p ], 'invalid-title' ); } } else { $badFileContextTitle = false; @@ -301,7 +302,7 @@ class ApiQueryImageInfo extends ApiQueryBase { $paramList = $h->parseParamString( $otherParams ); if ( !$paramList ) { - // Just set a warning (instead of dieUsage), as in many cases + // Just set a warning (instead of dieWithError), as in many cases // we could still render the image using width and height parameters, // and this type of thing could happen between different versions of // handlers. diff --git a/includes/api/ApiQueryLogEvents.php b/includes/api/ApiQueryLogEvents.php index 39be2c17fd..2d95cd3d18 100644 --- a/includes/api/ApiQueryLogEvents.php +++ b/includes/api/ApiQueryLogEvents.php @@ -263,32 +263,6 @@ class ApiQueryLogEvents extends ApiQueryBase { $result->addIndexedTagName( [ 'query', $this->getModuleName() ], 'item' ); } - /** - * @deprecated since 1.25 Use LogFormatter::formatParametersForApi instead - * @param ApiResult $result - * @param array &$vals - * @param string $params - * @param string $type - * @param string $action - * @param string $ts - * @param bool $legacy - * @return array - */ - public static function addLogParams( $result, &$vals, $params, $type, - $action, $ts, $legacy = false - ) { - wfDeprecated( __METHOD__, '1.25' ); - - $entry = new ManualLogEntry( $type, $action ); - $entry->setParameters( $params ); - $entry->setTimestamp( $ts ); - $entry->setLegacy( $legacy ); - $formatter = LogFormatter::newFromEntry( $entry ); - $vals['params'] = $formatter->formatParametersForApi(); - - return $vals; - } - private function extractRowInfo( $row ) { $logEntry = DatabaseLogEntry::newFromRow( $row ); $vals = [ diff --git a/includes/api/ApiUsageException.php b/includes/api/ApiUsageException.php index 7f8a26b89a..f930452737 100644 --- a/includes/api/ApiUsageException.php +++ b/includes/api/ApiUsageException.php @@ -24,12 +24,8 @@ * If possible, use ApiBase::dieWithError() instead of throwing this directly. * * @ingroup API - * @note This currently extends UsageException for backwards compatibility, so - * all the existing code that catches UsageException won't break when stuff - * starts throwing ApiUsageException. Eventually UsageException will go away - * and this will (probably) extend MWException directly. */ -class ApiUsageException extends UsageException implements ILocalizedException { +class ApiUsageException extends MWException implements ILocalizedException { protected $modulePath; protected $status; @@ -53,12 +49,7 @@ class ApiUsageException extends UsageException implements ILocalizedException { // customized by the local wiki. $enMsg = clone $this->getApiMessage(); $enMsg->inLanguage( 'en' )->useDatabase( false ); - parent::__construct( - ApiErrorFormatter::stripMarkup( $enMsg->text() ), - $enMsg->getApiCode(), - $httpCode, - $enMsg->getApiData() - ); + parent::__construct( ApiErrorFormatter::stripMarkup( $enMsg->text() ), $httpCode ); } /** @@ -111,32 +102,6 @@ class ApiUsageException extends UsageException implements ILocalizedException { return $this->status; } - /** - * @deprecated Do not use. This only exists here because UsageException is in - * the inheritance chain for backwards compatibility. - * @inheritDoc - */ - public function getCodeString() { - wfDeprecated( __METHOD__, '1.29' ); - return $this->getApiMessage()->getApiCode(); - } - - /** - * @deprecated Do not use. This only exists here because UsageException is in - * the inheritance chain for backwards compatibility. - * @inheritDoc - */ - public function getMessageArray() { - wfDeprecated( __METHOD__, '1.29' ); - $enMsg = clone $this->getApiMessage(); - $enMsg->inLanguage( 'en' )->useDatabase( false ); - - return [ - 'code' => $enMsg->getApiCode(), - 'info' => ApiErrorFormatter::stripMarkup( $enMsg->text() ), - ] + $enMsg->getApiData(); - } - /** * @inheritDoc */ diff --git a/includes/api/UsageException.php b/includes/api/UsageException.php deleted file mode 100644 index 426ce91cef..0000000000 --- a/includes/api/UsageException.php +++ /dev/null @@ -1,90 +0,0 @@ -mCodestr = $codestr; - $this->mExtraData = $extradata; - - if ( !$this instanceof ApiUsageException ) { - wfDeprecated( __METHOD__, '1.29' ); - } - - // This should never happen, so throw an exception about it that will - // hopefully get logged with a backtrace (T138585) - if ( !is_string( $codestr ) || $codestr === '' ) { - throw new InvalidArgumentException( 'Invalid $codestr, was ' . - ( $codestr === '' ? 'empty string' : gettype( $codestr ) ) - ); - } - } - - /** - * @return string - */ - public function getCodeString() { - wfDeprecated( __METHOD__, '1.29' ); - return $this->mCodestr; - } - - /** - * @return array - */ - public function getMessageArray() { - wfDeprecated( __METHOD__, '1.29' ); - $result = [ - 'code' => $this->mCodestr, - 'info' => $this->getMessage() - ]; - if ( is_array( $this->mExtraData ) ) { - $result = array_merge( $result, $this->mExtraData ); - } - - return $result; - } - - /** - * @return string - */ - public function __toString() { - return "{$this->getCodeString()}: {$this->getMessage()}"; - } -} diff --git a/includes/api/i18n/en.json b/includes/api/i18n/en.json index 253380c978..68cc07a030 100644 --- a/includes/api/i18n/en.json +++ b/includes/api/i18n/en.json @@ -1678,6 +1678,7 @@ "apierror-assertnameduserfailed": "Assertion that the user is \"$1\" failed.", "apierror-assertuserfailed": "Assertion that the user is logged in failed.", "apierror-autoblocked": "Your IP address has been blocked automatically, because it was used by a blocked user.", + "apierror-bad-badfilecontexttitle": "Invalid title in $1badfilecontexttitle parameter.", "apierror-badconfig-resulttoosmall": "The value of $wgAPIMaxResultSize on this wiki is too small to hold basic result information.", "apierror-badcontinue": "Invalid continue param. You should pass the original value returned by the previous query.", "apierror-baddiff": "The diff cannot be retrieved. One or both revisions do not exist or you do not have permission to view them.", @@ -1895,7 +1896,6 @@ "apiwarn-deprecation-withreplacement": "$1 has been deprecated. Please use $2 instead.", "apiwarn-difftohidden": "Couldn't diff to r$1: content is hidden.", "apiwarn-errorprinterfailed": "Error printer failed. Will retry without params.", - "apiwarn-errorprinterfailed-ex": "Error printer failed (will retry without params): $1", "apiwarn-ignoring-invalid-templated-value": "Ignoring value $2 in $1 when processing templated parameters.", "apiwarn-invalidcategory": "\"$1\" is not a category.", "apiwarn-invalidtitle": "\"$1\" is not a valid title.", diff --git a/includes/api/i18n/qqq.json b/includes/api/i18n/qqq.json index eb3fdef0e4..1cfc683181 100644 --- a/includes/api/i18n/qqq.json +++ b/includes/api/i18n/qqq.json @@ -1566,6 +1566,7 @@ "apierror-assertnameduserfailed": "{{doc-apierror}}\n\nParameters:\n* $1 - User name passed in.", "apierror-assertuserfailed": "{{doc-apierror}}", "apierror-autoblocked": "{{doc-apierror}}", + "apierror-bad-badfilecontexttitle": "{{doc-apierror}}\n\nParameters:\n* $1 - Module parameter prefix, e.g. \"bl\".", "apierror-badconfig-resulttoosmall": "{{doc-apierror}}", "apierror-badcontinue": "{{doc-apierror}}", "apierror-baddiff": "{{doc-apierror}}", @@ -1782,7 +1783,6 @@ "apiwarn-deprecation-withreplacement": "{{doc-apierror}}\n\nParameters:\n* $1 - Query string fragment that is deprecated, e.g. \"action=tokens\".\n* $2 - Query string fragment to use instead, e.g. \"action=tokens\".", "apiwarn-difftohidden": "{{doc-apierror}}\n\nParameters:\n* $1 - Revision ID number.\n\n\"r\" is short for \"revision\". You may translate it.", "apiwarn-errorprinterfailed": "{{doc-apierror}}", - "apiwarn-errorprinterfailed-ex": "{{doc-apierror}}\n\nParameters:\n* $1 - Exception message, which may already end in punctuation. Probably in English.", "apiwarn-ignoring-invalid-templated-value": "{{doc-apierror}}\n\nParameters:\n* $1 - Target parameter having a bad value.\n* $2 - The bad value being ignored.", "apiwarn-invalidcategory": "{{doc-apierror}}\n\nParameters:\n* $1 - Supplied category name.", "apiwarn-invalidtitle": "{{doc-apierror}}\n\nParameters:\n* $1 - Supplied title.", diff --git a/includes/specials/SpecialApiHelp.php b/includes/specials/SpecialApiHelp.php index 54480132e4..c725d106e1 100644 --- a/includes/specials/SpecialApiHelp.php +++ b/includes/specials/SpecialApiHelp.php @@ -82,11 +82,6 @@ class SpecialApiHelp extends UnlistedSpecialPage { $this->msg( 'apihelp-no-such-module', $moduleName )->inContentLanguage()->parse() ) ); return; - } catch ( UsageException $ex ) { - $this->getOutput()->addHTML( Html::rawElement( 'span', [ 'class' => 'error' ], - $this->msg( 'apihelp-no-such-module', $moduleName )->inContentLanguage()->parse() - ) ); - return; } ApiHelp::getHelp( $this->getContext(), $module, $options ); diff --git a/tests/phpunit/includes/api/ApiErrorFormatterTest.php b/tests/phpunit/includes/api/ApiErrorFormatterTest.php index f36faf7fed..144586e517 100644 --- a/tests/phpunit/includes/api/ApiErrorFormatterTest.php +++ b/tests/phpunit/includes/api/ApiErrorFormatterTest.php @@ -526,10 +526,6 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase { * @param array $expect */ public function testGetMessageFromException( $exception, $options, $expect ) { - if ( $exception instanceof UsageException ) { - $this->hideDeprecated( 'UsageException::getMessageArray' ); - } - $result = new ApiResult( 8388608 ); $formatter = new ApiErrorFormatter( $result, Language::factory( 'en' ), 'html', false ); @@ -555,10 +551,6 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase { * @param array $expect */ public function testGetMessageFromException_BC( $exception, $options, $expect ) { - if ( $exception instanceof UsageException ) { - $this->hideDeprecated( 'UsageException::getMessageArray' ); - } - $result = new ApiResult( 8388608 ); $formatter = new ApiErrorFormatter_BackCompat( $result ); @@ -579,12 +571,6 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase { } public static function provideGetMessageFromException() { - Wikimedia\suppressWarnings(); - $usageException = new UsageException( - 'Something broke!', 'ue-code', 0, [ 'xxx' => 'yyy', 'baz' => 23 ] - ); - Wikimedia\restoreWarnings(); - return [ 'Normal exception' => [ new RuntimeException( 'Something broke!' ), @@ -604,24 +590,6 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase { 'data' => [ 'foo' => 'bar', 'baz' => 42 ], ] ], - 'UsageException' => [ - $usageException, - [], - [ - 'text' => '<b>Something broke!</b>', - 'code' => 'ue-code', - 'data' => [ 'xxx' => 'yyy', 'baz' => 23 ], - ] - ], - 'UsageException, wrapped' => [ - $usageException, - [ 'wrap' => 'parentheses', 'code' => 'some-code', 'data' => [ 'foo' => 'bar', 'baz' => 42 ] ], - [ - 'text' => '(<b>Something broke!</b>)', - 'code' => 'some-code', - 'data' => [ 'xxx' => 'yyy', 'baz' => 42, 'foo' => 'bar' ], - ] - ], 'LocalizedException' => [ new LocalizedException( [ 'returnto', 'FooBar' ] ), [], diff --git a/tests/phpunit/includes/api/ApiMainTest.php b/tests/phpunit/includes/api/ApiMainTest.php index 20d758e3aa..a6083cda89 100644 --- a/tests/phpunit/includes/api/ApiMainTest.php +++ b/tests/phpunit/includes/api/ApiMainTest.php @@ -1010,10 +1010,6 @@ class ApiMainTest extends ApiTestCase { MWExceptionHandler::getRedactedTraceAsString( $dbex ) )->inLanguage( 'en' )->useDatabase( false )->text(); - Wikimedia\suppressWarnings(); - $usageEx = new UsageException( 'Usage exception!', 'ue', 0, [ 'foo' => 'bar' ] ); - Wikimedia\restoreWarnings(); - $apiEx1 = new ApiUsageException( null, StatusValue::newFatal( new ApiRawMessage( 'An error', 'sv-error1' ) ) ); TestingAccessWrapper::newFromObject( $apiEx1 )->modulePath = 'foo+bar'; @@ -1059,23 +1055,6 @@ class ApiMainTest extends ApiTestCase { 'servedby' => wfHostname(), ] ], - [ - $usageEx, - [ 'existing-error', 'ue' ], - [ - 'warnings' => [ - [ 'code' => 'existing-warning', 'text' => 'existing warning', 'module' => 'main' ], - ], - 'errors' => [ - [ 'code' => 'existing-error', 'text' => 'existing error', 'module' => 'main' ], - [ 'code' => 'ue', 'text' => "Usage exception!", 'data' => [ 'foo' => 'bar' ] ] - ], - 'docref' => "See $doclink for API usage. Subscribe to the mediawiki-api-announce mailing " . - "list at <https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce> " . - "for notice of API deprecations and breaking changes.", - 'servedby' => wfHostname(), - ] - ], [ $apiEx1, [ 'existing-error', 'sv-error1', 'sv-error2' ], -- 2.20.1