Repository: LeMyst/WikibaseIntegrator

Issue:
KeyError:'info' in MWApiError.__init__()
In the mediawiki_api_call() function, if 'error' is in json_data and none of the specific cases is occuring, a MWApiError is raised. In that MWApiError, in the __init__, error_dict['info'] is used, without checking if that key exists. In my case, it does not, so the script fails without giving information about the response, with KeyError: 'info' . It would be helpful, if at least the response string would be printed in case the 'info' key is not in error_dict.



Discussion:

Patch:
diff --git a/wikibaseintegrator/wbi_exceptions.py b/wikibaseintegrator/wbi_exceptions.py
index 29c5b24..648e762 100644
--- a/wikibaseintegrator/wbi_exceptions.py
+++ b/wikibaseintegrator/wbi_exceptions.py
@@ -6,7 +6,7 @@ class MWApiError(Exception):
     Base class for MediaWiki API error handling
     """
     code: str
-    info: Dict[str, Any]
+    info: str
     messages: List[Dict[str, Any]]
     messages_names: List[str]
 
@@ -41,11 +41,18 @@ class MWApiError(Exception):
         )
 
     def __init__(self, error_dict: Dict[str, Any]):
-        super().__init__(error_dict['info'])
-        self.code = error_dict['code']
-        self.info = error_dict['info']
-        self.messages = error_dict['messages']
-        self.messages_names = [message['name'] for message in error_dict['messages']]
+        if 'info' in error_dict:
+            self.info = error_dict['info']
+        else:
+            self.info = 'MWApiError'
+        super().__init__(self.info)
+        self.code = error_dict['code'] if 'code' in error_dict else 'wikibaseintegrator-missing-error-code'
+        if 'messages' in error_dict:
+            self.messages = error_dict['messages']
+            self.messages_names = [message['name'] for message in error_dict['messages']]
+        else:
+            self.messages = [{'html': {'*': 'WikibaseIntegrator: missing message from HTML return.'}, 'name': 'wikibaseintegrator-missing-messages'}]
+            self.messages_names = ['wikibaseintegrator-missing-messages']
 
     def __str__(self):
         return repr(self.info)


Test patch:
diff --git a/test/test_wbi_exceptions.py b/test/test_wbi_exceptions.py
index d535529..bee5b3e 100644
--- a/test/test_wbi_exceptions.py
+++ b/test/test_wbi_exceptions.py
@@ -51,8 +51,8 @@ class TestWbiExceptions(TestCase):
                                 },
                       'servedby': 'mw1375'}
 
-        with self.assertRaises(KeyError):
-            ModificationFailed(error_dict['error'])
+        exception = ModificationFailed(error_dict['error'])
+        assert 'wikibaseintegrator-missing-messages' in exception.messages_names
 
     def test_failed_save_no_conflict(self):
         error_dict = {'error': {'*': 'See https://test.wikidata.org/w/api.php for API usage. '
@@ -134,3 +134,11 @@ class TestWbiExceptions(TestCase):
     @staticmethod
     def test_searcherror():
         assert str(SearchError('SearchError')) == 'SearchError'
+
+    def test_modification_failed_error_dict(self):
+        error_dict = {'error': {}}
+
+        exception = ModificationFailed(error_dict['error'])
+        assert 'wikibaseintegrator-missing-messages' in exception.messages_names
+        assert exception.info == 'MWApiError'
+        assert exception.code == 'wikibaseintegrator-missing-error-code'