X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fapi%2FApiMain.php;h=bc76f8f306f7bf225d14629644791f8f2d7f4603;hb=75c17a4cdaf8f1ff594ba5e62fcf6edd5076ab4a;hp=3b305f9e5c907132a18daa2eeb88c47a1f8da3f0;hpb=0e56ff447bbb74df007f2573725baaa61ed2745c;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php index 3b305f9e5c..bc76f8f306 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; @@ -841,7 +834,11 @@ class ApiMain extends ApiBase { foreach ( $requestedHeaders as $rHeader ) { $rHeader = strtolower( trim( $rHeader ) ); if ( !isset( $allowedAuthorHeaders[$rHeader] ) ) { - wfDebugLog( 'api', 'CORS preflight failed on requested header: ' . $rHeader ); + LoggerFactory::getInstance( 'api-warning' )->warning( + 'CORS preflight failed on requested header: {header}', [ + 'header' => $rHeader + ] + ); return false; } } @@ -1012,9 +1009,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,18 +1026,13 @@ 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(); + // 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( 'ShowExceptionDetails' ) ) { if ( $e instanceof ILocalizedException ) { $msg = $e->getMessageObject(); @@ -1057,7 +1046,7 @@ class ApiMain extends ApiBase { $params = [ 'apierror-exceptioncaughttype', WebRequest::getRequestId(), get_class( $e ) ]; } - $messages[] = ApiMessage::create( $params, $code ); + $messages[] = ApiMessage::create( $params, $code, $data ); } return $messages; } @@ -1094,7 +1083,15 @@ class ApiMain extends ApiBase { // Add errors from the exception $modulePath = $e instanceof ApiUsageException ? $e->getModulePath() : null; foreach ( $this->errorMessagesFromException( $e, 'error' ) as $msg ) { - $errorCodes[$msg->getApiCode()] = true; + if ( ApiErrorFormatter::isValidApiCode( $msg->getApiCode() ) ) { + $errorCodes[$msg->getApiCode()] = true; + } else { + LoggerFactory::getInstance( 'api-warning' )->error( 'Invalid API error code "{code}"', [ + 'code' => $msg->getApiCode(), + 'exception' => $e, + ] ); + $errorCodes[''] = true; + } $formatter->addError( $modulePath, $msg ); } foreach ( $this->errorMessagesFromException( $e, 'warning' ) as $msg ) { @@ -1108,7 +1105,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, @@ -1481,9 +1478,14 @@ class ApiMain extends ApiBase { if ( $numLagged >= ceil( $replicaCount / 2 ) ) { $laggedServers = implode( ', ', $laggedServers ); wfDebugLog( - 'api-readonly', + 'api-readonly', // Deprecate this channel in favor of api-warning? "Api request failed as read only because the following DBs are lagged: $laggedServers" ); + LoggerFactory::getInstance( 'api-warning' )->warning( + "Api request failed as read only because the following DBs are lagged: {laggeddbs}", [ + 'laggeddbs' => $laggedServers, + ] + ); $this->dieWithError( 'readonly_lag', @@ -1529,7 +1531,13 @@ class ApiMain extends ApiBase { * @param array $params An array with the request parameters */ protected function setupExternalResponse( $module, $params ) { + $validMethods = [ 'GET', 'HEAD', 'POST', 'OPTIONS' ]; $request = $this->getRequest(); + + if ( !in_array( $request->getMethod(), $validMethods ) ) { + $this->dieWithError( 'apierror-invalidmethod', null, null, 405 ); + } + if ( !$request->wasPosted() && $module->mustBePosted() ) { // Module requires POST. GET request might still be allowed // if $wgDebugApi is true, otherwise fail.