Skip to content

Commit

Permalink
Merge "REST: Refactor EntityUpdater error handling"
Browse files Browse the repository at this point in the history
  • Loading branch information
jenkins-bot authored and Gerrit Code Review committed Sep 30, 2024
2 parents 7574653 + b2a0a5c commit cecf840
Showing 1 changed file with 26 additions and 55 deletions.
81 changes: 26 additions & 55 deletions repo/rest-api/src/Infrastructure/DataAccess/EntityUpdater.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use LogicException;
use MediaWiki\Context\IContextSource;
use MediaWiki\Permissions\PermissionManager;
use MediaWiki\Status\Status;
use MediaWiki\User\User;
use MessageSpecifier;
use Psr\Log\LoggerInterface;
Expand Down Expand Up @@ -104,7 +103,9 @@ private function createOrUpdate(
try {
$this->entityStore->assignFreshId( $entity );
} catch ( StorageException $e ) {
$this->throwIfRateLimitReached( $e->getStatus() );
if ( $e->getStatus()->hasMessage( 'actionthrottledtext' ) ) {
throw new RateLimitReached();
}
throw $e; // It wasn't a rate limit error, so we rethrow as an unexpected exception.
}
}
Expand All @@ -125,28 +126,17 @@ private function createOrUpdate(
);

if ( !$status->isOK() ) {
$entityTooBigError = $this->findErrorInStatus( $status, 'wikibase-error-entity-too-big' );
if ( $entityTooBigError ) {
if ( $status->hasMessage( 'wikibase-error-entity-too-big' ) ) {
throw new ResourceTooLargeException( $this->repoSettings->getSetting( 'maxSerializedEntitySize' ) );
}

$abuseFilterError = $this->findAbuseFilterError( $status->getMessages() );
if ( $abuseFilterError ) {
throw new AbuseFilterException(
$abuseFilterError->getApiData()['abusefilter']['id'],
$abuseFilterError->getApiData()['abusefilter']['description']
);
}

$this->throwIfRateLimitReached( $status );

if ( $this->findErrorInStatus( $status, 'acct_creation_throttle_hit' ) ) {
} elseif ( $status->hasMessage( 'acct_creation_throttle_hit' ) ) {
throw new TempAccountCreationLimitReached();
} elseif ( $status->hasMessage( 'actionthrottledtext' ) ) {
throw new RateLimitReached();
}

$spamBlacklistError = $this->findSpamBlacklistError( $status->getMessages() );
if ( $spamBlacklistError ) {
throw new SpamBlacklistException( $spamBlacklistError->getApiData()['spamblacklist']['matches'][0] );
foreach ( $status->getMessages() as $message ) {
$this->throwIfAbuseFilterError( $message );
$this->throwIfSpamBlacklistError( $message );
}

throw new EntityUpdateFailed( (string)$status );
Expand All @@ -157,36 +147,26 @@ private function createOrUpdate(
return $status->getRevision();
}

private function findErrorInStatus( Status $status, string $errorCode ): ?MessageSpecifier {
foreach ( $status->getMessages() as $message ) {
// prefix comparison to cover different kinds of errors
if ( strpos( $message->getKey(), $errorCode ) === 0 ) {
return $message;
}
}

return null;
}

private function findAbuseFilterError( array $messages ): ?IApiMessage {
foreach ( $messages as $message ) {
if ( $message instanceof IApiMessage &&
in_array( $message->getApiCode(), [ 'abusefilter-warning', 'abusefilter-disallowed' ] ) ) {
return $message;
}
/**
* @throws AbuseFilterException
*/
private function throwIfAbuseFilterError( MessageSpecifier $message ): void {
if ( $message instanceof IApiMessage &&
in_array( $message->getApiCode(), [ 'abusefilter-warning', 'abusefilter-disallowed' ] ) ) {
throw new AbuseFilterException(
$message->getApiData()['abusefilter']['id'],
$message->getApiData()['abusefilter']['description']
);
}

return null;
}

private function findSpamBlacklistError( array $messages ): ?IApiMessage {
foreach ( $messages as $message ) {
if ( $message instanceof IApiMessage && $message->getApiCode() === 'spamblacklist' ) {
return $message;
}
/**
* @throws SpamBlacklistException
*/
private function throwIfSpamBlacklistError( MessageSpecifier $message ): void {
if ( $message instanceof IApiMessage && $message->getApiCode() === 'spamblacklist' ) {
throw new SpamBlacklistException( $message->getApiData()['spamblacklist']['matches'][0] );
}

return null;
}

private function checkBotRightIfProvided( User $user, bool $isBot ): void {
Expand All @@ -204,13 +184,4 @@ private function generateStatementIds( StatementListProvidingEntity $entity ): v
}
}

/**
* @throws RateLimitReached
*/
private function throwIfRateLimitReached( Status $status ): void {
if ( $this->findErrorInStatus( $status, 'actionthrottledtext' ) ) {
throw new RateLimitReached();
}
}

}

0 comments on commit cecf840

Please sign in to comment.