From bd0c1a26c244e3075f538d01c65d195bc0aa6a16 Mon Sep 17 00:00:00 2001 From: Edward Betts Date: Mon, 18 May 2026 23:20:40 +0100 Subject: [PATCH] Raise edit API errors with response details --- add_links/mediawiki_api.py | 17 +++++++++----- test_mediawiki_api.py | 46 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 test_mediawiki_api.py diff --git a/add_links/mediawiki_api.py b/add_links/mediawiki_api.py index 611ab5b..8319c37 100644 --- a/add_links/mediawiki_api.py +++ b/add_links/mediawiki_api.py @@ -1,7 +1,6 @@ """Interface with the mediawiki API.""" import typing -from pprint import pprint from typing import Any, cast import requests @@ -12,6 +11,17 @@ from . import mediawiki_oauth class APIError(Exception): """Unexpected response from the MediaWiki API.""" + +def _format_api_error(data: dict[str, Any]) -> str: + """Format a MediaWiki API error response.""" + error = data.get("error") + if isinstance(error, dict): + message = error.get("info") or error.get("code") + if message: + return str(message) + return f"Unexpected MediaWiki API response: {data!r}" + + wiki_hostname = "en.wikipedia.org" wiki_api_php = f"https://{wiki_hostname}/w/api.php" user_agent = "add-links/0.1" @@ -103,8 +113,5 @@ def edit_page( } ret = call(params, timeout=30) if "edit" not in ret: - print("params") - pprint(params) - print() - pprint(ret) + raise APIError(_format_api_error(ret)) return typing.cast(str, ret["edit"]) diff --git a/test_mediawiki_api.py b/test_mediawiki_api.py new file mode 100644 index 0000000..b9fdd34 --- /dev/null +++ b/test_mediawiki_api.py @@ -0,0 +1,46 @@ +import unittest +from unittest.mock import patch + +from add_links import mediawiki_api + + +class EditPageTests(unittest.TestCase): + def test_edit_page_raises_api_error_with_mediawiki_message(self) -> None: + with patch( + "add_links.mediawiki_api.call", + return_value={"error": {"code": "badtoken", "info": "Invalid CSRF token."}}, + ): + with self.assertRaises(mediawiki_api.APIError) as ctx: + mediawiki_api.edit_page( + pageid=1, + section=0, + text="text", + summary="summary", + baserevid="123", + token="bad", + ) + + self.assertEqual(str(ctx.exception), "Invalid CSRF token.") + + def test_edit_page_raises_api_error_for_unexpected_response(self) -> None: + response = {"servedby": "mw-api-ext.eqiad.main"} + + with patch("add_links.mediawiki_api.call", return_value=response): + with self.assertRaises(mediawiki_api.APIError) as ctx: + mediawiki_api.edit_page( + pageid=1, + section=0, + text="text", + summary="summary", + baserevid="123", + token="token", + ) + + self.assertEqual( + str(ctx.exception), + "Unexpected MediaWiki API response: {'servedby': 'mw-api-ext.eqiad.main'}", + ) + + +if __name__ == "__main__": + unittest.main()