jenkins-bot submitted this change.

View Change


Approvals: JJMC89: Looks good to me, approved jenkins-bot: Verified
[IMPR] Raise APIError if the same error comes twice within submit loop

api.Request.submit handles API errors within a loop but in some
circumstances the loop will never leaved if the same error comes again
and again. Therefore raise APIError with the previous API error if the
same error occured twice in the same submit loop-

Bug: T357870
Change-Id: Id9f140c9d8815ef622d47cd90a29518f23665a4a
---
M pywikibot/data/api/_requests.py
1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/pywikibot/data/api/_requests.py b/pywikibot/data/api/_requests.py
index bc40eec..8facad1 100644
--- a/pywikibot/data/api/_requests.py
+++ b/pywikibot/data/api/_requests.py
@@ -1,6 +1,6 @@
"""Objects representing API requests."""
#
-# (C) Pywikibot team, 2007-2023
+# (C) Pywikibot team, 2007-2024
#
# Distributed under the terms of the MIT license.
#
@@ -945,18 +945,36 @@
self._params['token'] = tokens
return True

+ def wait(self, delay: int | None = None) -> None:
+ """Determine how long to wait after a failed request.
+
+ Also reset last API error with wait cycles.
+
+ .. versionadded: 9.0
+
+ :param delay: Minimum time in seconds to wait. Overwrites
+ ``retry_wait`` variable if given. The delay doubles each
+ retry until ``retry_max`` seconds is reached.
+ """
+ self.last_error = dict.fromkeys(['code', 'info'])
+ super().wait(delay)
+
def submit(self) -> dict:
"""Submit a query and parse the response.

.. versionchanged:: 8.0.4
in addition to *readapidenied* also try to login when API
response is *notloggedin*.
+ .. versionchanged:: 9.0
+ Raise :exc:`pywikibot.exceptions.APIError` if the same error
+ comes twice in a row within the loop.

:return: a dict containing data retrieved from api.php
"""
self._add_defaults()
use_get = self._use_get()
retries = 0
+ self.last_error = dict.fromkeys(['code', 'info'])
while True:
paramstring = self._http_param_string()

@@ -1003,6 +1021,11 @@
code = error.setdefault('code', 'Unknown')
info = error.setdefault('info', None)

+ if (code == self.last_error['code']
+ and info == self.last_error['info']):
+ raise pywikibot.exceptions.APIError(**self.last_error)
+ self.last_error = error
+
if not self._logged_in(code):
continue

@@ -1019,6 +1042,8 @@
lag = float(lag['lag']) if lag else 0.0

self.site.throttle.lag(lag * retries)
+ # reset last error
+ self.last_error = dict.fromkeys(['code', 'info'])
continue

if code == 'help' and self.action == 'help':
@@ -1060,6 +1085,7 @@
pywikibot.error(f'Retrying failed {msg}')
continue
raise NoUsernameError(f'Failed {msg}')
+
if code == 'cirrussearch-too-busy-error': # T170647
self.wait()
continue

To view, visit change 1004618. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Id9f140c9d8815ef622d47cd90a29518f23665a4a
Gerrit-Change-Number: 1004618
Gerrit-PatchSet: 4
Gerrit-Owner: Xqt <info@gno.de>
Gerrit-Reviewer: JJMC89 <JJMC89.Wikimedia@gmail.com>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged