Open lucaswerkmeister opened 5 years ago
I’m not sure what
mwapi
should do in this case, though. Throw anAPIError
for the first error and ignore the rest? Define a new exception class for a list ofAPIError
s (which should probably derive fromAPIError
so it can still be caught like one)?
PEP 654 proposes exception groups (LWN.net article), which might be an interesting answer to this question.
Exception groups and except*
are released in Python 3.11 now (see the PEP for details). I’m not sure they’re a good fit for mwapi, though: the main motivation for exception groups seems to be situations where the original exceptions come from different sources, and they repeatedly mention that a handler of an exception group would typically not handle the specific exceptions in great detail:
Neither of these matches the mwapi situation.
Code to test the behavior with multiple errors:
import mwapi
session = mwapi.Session(host='https://test.wikipedia.org',
user_agent='mwapi-errors-test (https://github.com/mediawiki-utilities/python-mwapi/issues/34; mail@lucaswerkmeister.de)')
token = session.get(action='query',
meta='tokens',
type='csrf')['query']['tokens']['csrftoken']
params = {
'action': 'edit',
'title': 'Sandbox',
'appendtext': 'the abuse filter will block this\nthe abuse filter will also block this',
'token': token,
}
for errorformat in ['bc', 'plaintext']:
try:
response = session.post(errorformat=errorformat, **params)
print(f'{errorformat=} did not throw, {response=}')
except mwapi.errors.APIError as exception:
print(f'{errorformat=} did throw, {exception=}')
Current output:
errorformat='bc' did throw, exception=APIError('abusefilter-disallowed: This action has been automatically identified as harmful, and therefore disallowed. If you believe your action was constructive, please inform an administrator of what you were trying to do. A brief description of the abuse rule which your action matched is: No saying "The abuse filter will block this" -- See https://test.wikipedia.org/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/postorius/lists/mediawiki-api-announce.lists.wikimedia.org/> for notice of API deprecations and breaking changes.')
errorformat='plaintext' did not throw, response={'errors': [{'code': 'abusefilter-disallowed', 'data': {'abusefilter': {'id': '1', 'description': 'No saying "The abuse filter will block this"', 'actions': ['disallow']}}, 'module': 'edit', '*': 'This action has been automatically identified as harmful, and therefore disallowed. If you believe your action was constructive, please inform an administrator of what you were trying to do. A brief description of the abuse rule which your action matched is: No saying "The abuse filter will block this"'}, {'code': 'abusefilter-disallowed', 'data': {'abusefilter': {'id': '266', 'description': 'No saying "The abuse filter will also block this"', 'actions': ['disallow']}}, 'module': 'edit', '*': 'This action has been automatically identified as harmful, and therefore disallowed. If you believe your action was constructive, please inform an administrator of what you were trying to do. A brief description of the abuse rule which your action matched is: No saying "The abuse filter will also block this"'}], 'servedby': 'mw1359', '*': 'See https://test.wikipedia.org/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/postorius/lists/mediawiki-api-announce.lists.wikimedia.org/> for notice of API deprecations and breaking changes.'}
(Notice that errorformat=bc
only reports one of the two AbuseFilter errors.)
Since MediaWiki 1.29, the API can return errors in a new format (documentation): if the global
errorformat
parameter is set to anything other thanbc
(the default, for backwards compatibility), then instead of a singleerror
object, the response can contain anerrors
list of error objects. Sincemwapi
currently only checks if the response contains anerror
, if the user specifies a different error format thenmwapi
will not recognize the error(s) and instead return the result as a regular response.I’m not sure what
mwapi
should do in this case, though. Throw anAPIError
for the first error and ignore the rest? Define a new exception class for a list ofAPIError
s (which should probably derive fromAPIError
so it can still be caught like one)?