ApiErrorFormatter_BackCompat: Use first error, not last
authorBrad Jorsch <bjorsch@wikimedia.org>
Tue, 17 Jan 2017 15:51:27 +0000 (10:51 -0500)
committerBrad Jorsch <bjorsch@wikimedia.org>
Tue, 17 Jan 2017 16:00:55 +0000 (11:00 -0500)
Before Iae0e2ce3b, the only place in the API that had to deal with
choosing from multiple errors was ApiBase::dieStatus(), which chose the
first one in the Status object. Iae0e2ce3b changed this to choose the
last one instead, which is an unnecessary backwards compatibility break.

While we could make the change in ApiBase::dieStatus(), it's cleaner to
change ApiErrorFormatter_BackCompat's behavior instead since it seems
unlikely anything else was using that code path.

Bug: T155268
Change-Id: Ia06527f8480c3d4a689792ceb8671b0d399ffbe3

includes/api/ApiErrorFormatter.php
tests/phpunit/includes/api/ApiErrorFormatterTest.php

index 814004a..c52b731 100644 (file)
@@ -414,12 +414,17 @@ class ApiErrorFormatter_BackCompat extends ApiErrorFormatter {
 
                if ( $tag === 'error' ) {
                        // In BC mode, only one error
-                       $value = [
-                               'code' => $msg->getApiCode(),
-                               'info' => $value,
-                       ] + $msg->getApiData();
-                       $this->result->addValue( null, 'error', $value,
-                               ApiResult::OVERRIDE | ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
+                       $existingError = $this->result->getResultData( [ 'error' ] );
+                       if ( !is_array( $existingError ) ||
+                               !isset( $existingError['code'] ) || !isset( $existingError['info'] )
+                       ) {
+                               $value = [
+                                       'code' => $msg->getApiCode(),
+                                       'info' => $value,
+                               ] + $msg->getApiData();
+                               $this->result->addValue( null, 'error', $value,
+                                       ApiResult::OVERRIDE | ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
+                       }
                } else {
                        if ( $modulePath === null ) {
                                $moduleName = 'unknown';
index a40db24..eaa4d17 100644 (file)
@@ -439,8 +439,8 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase {
                $formatter->addMessagesFromStatus( 'status', $status );
                $this->assertSame( [
                        'error' => [
-                               'code' => 'parentheses',
-                               'info' => $parensPlain,
+                               'code' => 'mainpage',
+                               'info' => $mainpagePlain,
                        ],
                        'warnings' => [
                                'status' => [
@@ -502,6 +502,17 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase {
                        $formatter->arrayFromStatus( $status, 'warning' ),
                        'arrayFromStatus test for warning'
                );
+
+               $result->reset();
+               $result->addValue( null, 'error', [ 'bogus' ] );
+               $formatter->addError( 'err', 'mainpage' );
+               $this->assertSame( [
+                       'error' => [
+                               'code' => 'mainpage',
+                               'info' => $mainpagePlain,
+                       ],
+                       ApiResult::META_TYPE => 'assoc',
+               ], $result->getResultData(), 'Overwrites bogus "error" value with real error' );
        }
 
        /**