From c765b4e37cfb39ca41ece6e47c43885fd79d6454 Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Mon, 26 Nov 2018 13:31:41 -0500 Subject: [PATCH] API: Add exception class as data to internal_api_error codes The code for all uncaught exceptions will in the future be "internal_api_error". If the client needs to know the class name for some reason, it can check the new 'errorclass' data item on the error. Change-Id: Ia9e32bbb8d17692203f4fbcee53a20e87be1776e --- RELEASE-NOTES-1.33 | 6 ++++++ includes/api/ApiErrorFormatter.php | 1 + includes/api/ApiMain.php | 3 ++- tests/phpunit/includes/api/ApiErrorFormatterTest.php | 4 +++- tests/phpunit/includes/api/ApiMainTest.php | 10 ++++++++++ 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/RELEASE-NOTES-1.33 b/RELEASE-NOTES-1.33 index 422bbfa621..677b1c1874 100644 --- a/RELEASE-NOTES-1.33 +++ b/RELEASE-NOTES-1.33 @@ -55,6 +55,12 @@ production. === Action API changes in 1.33 === * (T198913) Added 'ApiOptions' hook. * The JSON formatversion=2 is no longer experimental. +* Internal API errors (those with code beginning "internal_api_error") will + include the exception class name in a data field named "errorclass". + * Class names are not guaranteed to remain stable, and in particular database + exceptions will now include the "Wikimedia\Rdbms\" prefix in the class name. + * The code including an exception class name is deprecated. In the future, + all internal errors will use code "internal_api_error". * … === Action API internal changes in 1.33 === diff --git a/includes/api/ApiErrorFormatter.php b/includes/api/ApiErrorFormatter.php index ef28b73715..a37ecc2df9 100644 --- a/includes/api/ApiErrorFormatter.php +++ b/includes/api/ApiErrorFormatter.php @@ -211,6 +211,7 @@ class ApiErrorFormatter { if ( !isset( $options['code'] ) ) { $class = preg_replace( '#^Wikimedia\\\Rdbms\\\#', '', get_class( $exception ) ); $options['code'] = 'internal_api_error_' . $class; + $options['data']['errorclass'] = get_class( $exception ); } } $params = [ wfEscapeWikiText( $exception->getMessage() ) ]; diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php index 162f0ce152..bc76f8f306 100644 --- a/includes/api/ApiMain.php +++ b/includes/api/ApiMain.php @@ -1032,6 +1032,7 @@ class ApiMain extends ApiBase { // 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(); @@ -1045,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; } diff --git a/tests/phpunit/includes/api/ApiErrorFormatterTest.php b/tests/phpunit/includes/api/ApiErrorFormatterTest.php index 65a511d85b..312ef55e8f 100644 --- a/tests/phpunit/includes/api/ApiErrorFormatterTest.php +++ b/tests/phpunit/includes/api/ApiErrorFormatterTest.php @@ -599,7 +599,9 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase { [ 'text' => '<b>Something broke!</b>', 'code' => 'internal_api_error_RuntimeException', - 'data' => [], + 'data' => [ + 'errorclass' => 'RuntimeException', + ], ] ], 'Normal exception, wrapped' => [ diff --git a/tests/phpunit/includes/api/ApiMainTest.php b/tests/phpunit/includes/api/ApiMainTest.php index 3299e73dc9..9cb84e23bc 100644 --- a/tests/phpunit/includes/api/ApiMainTest.php +++ b/tests/phpunit/includes/api/ApiMainTest.php @@ -1,5 +1,6 @@ 'internal_api_error_InvalidArgumentException', 'text' => "[$reqId] Exception caught: Random exception", + 'data' => [ + 'errorclass' => InvalidArgumentException::class, + ], ] ], 'trace' => $trace, @@ -1065,6 +1069,9 @@ class ApiMainTest extends ApiTestCase { 'code' => 'internal_api_error_DBQueryError', 'text' => "[$reqId] Exception caught: A database query error has occurred. " . "This may indicate a bug in the software.", + 'data' => [ + 'errorclass' => DBQueryError::class, + ], ] ], 'trace' => $dbtrace, @@ -1083,6 +1090,9 @@ class ApiMainTest extends ApiTestCase { [ 'code' => 'internal_api_error_MediaWiki\ShellDisabledError', 'text' => "[$reqId] Exception caught: " . $nsex->getMessage(), + 'data' => [ + 'errorclass' => MediaWiki\ShellDisabledError::class, + ], ] ], 'trace' => $nstrace, -- 2.20.1