improve error management and tests

This commit is contained in:
Guilhem Saurel 2021-07-14 23:25:24 +02:00
parent a0a78bbad0
commit 0c0a42a4c9
2 changed files with 39 additions and 10 deletions

View file

@ -17,6 +17,7 @@ from aiohttp import web
from markdown import markdown from markdown import markdown
from nio import AsyncClient from nio import AsyncClient
from nio.exceptions import LocalProtocolError from nio.exceptions import LocalProtocolError
from nio.responses import RoomSendError
parser = argparse.ArgumentParser(description=__doc__) parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument( parser.add_argument(
@ -81,6 +82,7 @@ MATRIX_PW = args.matrix_pw
API_KEY = args.api_key API_KEY = args.api_key
CLIENT = AsyncClient(args.matrix_url, args.matrix_id) CLIENT = AsyncClient(args.matrix_url, args.matrix_id)
LOGGER = logging.getLogger("matrix-webhook") LOGGER = logging.getLogger("matrix-webhook")
ERROR_MAP = {"M_FORBIDDEN": HTTPStatus.FORBIDDEN}
async def handler(request): async def handler(request):
@ -112,13 +114,26 @@ async def handler(request):
"format": "org.matrix.custom.html", "format": "org.matrix.custom.html",
"formatted_body": markdown(str(data["text"]), extensions=["extra"]), "formatted_body": markdown(str(data["text"]), extensions=["extra"]),
} }
for _ in range(10):
try: try:
await send_room_message(room_id, content) resp = await send_room_message(room_id, content)
except LocalProtocolError as e: # Connection lost, try another login if isinstance(resp, RoomSendError):
LOGGER.error(f"Send error: {e}") if resp.status_code == "M_UNKNOWN_TOKEN":
LOGGER.warning("Reconnecting and trying again") LOGGER.warning("Reconnecting")
await CLIENT.login(MATRIX_PW) await CLIENT.login(MATRIX_PW)
await send_room_message(room_id, content) else:
return create_json_response(
ERROR_MAP[resp.status_code], resp.message
)
else:
break
except LocalProtocolError as e:
LOGGER.error(f"Send error: {e}")
LOGGER.warning("Trying again")
else:
return create_json_response(
HTTPStatus.GATEWAY_TIMEOUT, "Homeserver not responding"
)
return create_json_response(HTTPStatus.OK, "OK") return create_json_response(HTTPStatus.OK, "OK")

View file

@ -20,9 +20,11 @@ class BotTest(unittest.IsolatedAsyncioTestCase):
self.assertEqual( self.assertEqual(
bot_req({"text": 3, "key": None}), {"status": 401, "ret": "Invalid API key"} bot_req({"text": 3, "key": None}), {"status": 401, "ret": "Invalid API key"}
) )
# TODO: if the client from matrix_webhook has olm support, this won't be a 403 from synapse,
# TODO: we are not sending to a real room, so this should not be "OK" # but a LocalProtocolError from matrix_webhook
self.assertEqual(bot_req({"text": 3}, KEY), {"status": 200, "ret": "OK"}) self.assertEqual(
bot_req({"text": 3}, KEY), {"status": 403, "ret": "Unknown room"}
)
async def test_message(self): async def test_message(self):
"""Send a markdown message, and check the result.""" """Send a markdown message, and check the result."""
@ -45,3 +47,15 @@ class BotTest(unittest.IsolatedAsyncioTestCase):
self.assertEqual(message.sender, FULL_ID) self.assertEqual(message.sender, FULL_ID)
self.assertEqual(message.body, text) self.assertEqual(message.body, text)
self.assertEqual(message.formatted_body, "<h1>Hello</h1>") self.assertEqual(message.formatted_body, "<h1>Hello</h1>")
async def test_reconnect(self):
"""Check the reconnecting path."""
client = nio.AsyncClient(MATRIX_URL, MATRIX_ID)
await client.login(MATRIX_PW)
room = await client.room_create()
await client.logout(all_devices=True)
await client.close()
self.assertEqual(
bot_req({"text": "Re"}, KEY, room.room_id),
{"status": 200, "ret": "OK"},
)