Skip to content

Commit

Permalink
Retry missing throttled actions
Browse files Browse the repository at this point in the history
  • Loading branch information
addshore committed Dec 18, 2015
1 parent 12db637 commit b50b89d
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 8 deletions.
3 changes: 3 additions & 0 deletions RELEASENOTES.md
@@ -1,5 +1,8 @@
These are the release notes for the [mediawiki-api-base](README.md).

## Version 2.0.1
* Retry throttled actions that return a failed-save code and anti-abuse message

## Version 2.0.0 (18 December 2015)
* Added `MediawikiApi::newFromApiEndpoint` and `MediawikiApi::newFromPage`
* MediawikiApi constructor access marked as private (please use static factory methods)
Expand Down
27 changes: 19 additions & 8 deletions src/Guzzle/MiddlewareFactory.php
Expand Up @@ -62,25 +62,36 @@ private function newRetryDecider() {

if( $response ) {
$headers = $response->getHeaders();
$data = json_decode( $response->getBody(), true );

// Retry on server errors
if( $response->getStatusCode() >= 500 ) {
$shouldRetry = true;
}

// Retry if we have a response with an API error worth retrying
if ( array_key_exists( 'mediawiki-api-error', $headers ) ) {
foreach( $headers['mediawiki-api-error'] as $mediawikiApiErrorHeader ) {
if ( in_array(
$mediawikiApiErrorHeader,
array(
'ratelimited',
'readonly',
'internal_api_error_DBQueryError',
if (
// Retry if we have a response with an API error worth retrying
in_array(
$mediawikiApiErrorHeader,
array(
'ratelimited',
'readonly',
'internal_api_error_DBQueryError',
)
)
) ) {
||
// Or if we have been stopped from saving as an 'anti-abuse measure'
// Note: this tries to match "actionthrottledtext" i18n messagae for mediawiki
(
$mediawikiApiErrorHeader == 'failed-save' &&
strstr( $data['error']['info'], 'anti-abuse measure' )
)
) {
$shouldRetry = true;
}

}
}
}
Expand Down
30 changes: 30 additions & 0 deletions tests/unit/Guzzle/MiddlewareFactoryTest.php
Expand Up @@ -77,6 +77,36 @@ public function testRetriesSomeMediawikiApiErrorHeaders() {
);
}

public function testRetryAntiAbuseMeasure() {
$middlewareFactory = new MiddlewareFactory();

$antiAbusejson = json_encode(
array(
'error' => array(
'info' => 'anti-abuse measure'
)
)
);

$mock = new MockHandler(
array(
new Response( 200, array( 'mediawiki-api-error' => 'failed-save' ), $antiAbusejson ),
new Response( 200, array( 'mediawiki-api-error' => 'DoNotRetryThisHeader' ) ),
)
);

$handler = HandlerStack::create( $mock );
$handler->push( $middlewareFactory->retry() );
$client = new Client( [ 'handler' => $handler ] );

$response = $client->request( 'GET', '/' );
$this->assertEquals( 200, $response->getStatusCode() );
$this->assertEquals(
array( 'DoNotRetryThisHeader' ),
$response->getHeader( 'mediawiki-api-error' )
);
}

public function testRetryLimit() {
$middlewareFactory = new MiddlewareFactory();

Expand Down

0 comments on commit b50b89d

Please sign in to comment.