From 6523a28e1194f955f43e7e769a3e907ef94c1863 Mon Sep 17 00:00:00 2001 From: Joel Beckmeyer Date: Wed, 28 Dec 2022 20:22:24 -0500 Subject: [PATCH] fix some pleroma errors with async and 500 errors (#4) * fix some pleroma errors with async and 500 errors * add better recovery/handling of HTTP 500 * remove unnecessary else --- pleroma.py | 5 +++++ reply.py | 20 ++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/pleroma.py b/pleroma.py index 91ed8e6..c726d0d 100644 --- a/pleroma.py +++ b/pleroma.py @@ -21,6 +21,9 @@ def http_session_factory(headers={}): class BadRequest(Exception): pass +class BadResponse(Exception): + pass + class Pleroma: def __init__(self, *, api_base_url, access_token): self.api_base_url = api_base_url.rstrip('/') @@ -50,6 +53,8 @@ class Pleroma: async with self._session.request(method, self.api_base_url + path, **kwargs) as resp: if resp.status == HTTPStatus.BAD_REQUEST: raise BadRequest((await resp.json())['error']) + if resp.status == HTTPStatus.INTERNAL_SERVER_ERROR: + raise BadResponse((await resp.json())) #resp.raise_for_status() return await resp.json() diff --git a/reply.py b/reply.py index c54df27..57fe2a6 100755 --- a/reply.py +++ b/reply.py @@ -22,10 +22,22 @@ class ReplyBot: async for notification in self.pleroma.stream_mentions(): await self.process_notification(notification) - async def process_notification(self, notification): + async def process_notification(self, notification, retry_count=0): acct = "@" + notification['account']['acct'] # get the account's @ post_id = notification['status']['id'] - context = await self.pleroma.status_context(post_id) + + # catch HTTP 500 and backoff on requests + retry_count = retry_count + 1 + try: + context = await self.pleroma.status_context(post_id) + except pleroma.BadResponse as exc: + if retry_count < 3: + await anyio.sleep(2**retry_count) + await self.process_notification(notification, retry_count) + else: + # failed too many times in a row, logging + print(f"Received HTTP 500 {retry_count} times in a row, aborting reply attempt.") + return # check if we've already been participating in this thread if self.check_thread_length(context): @@ -69,12 +81,12 @@ class ReplyBot: await self.pleroma.react(post_id, '✅') async def reply(self, notification): - toot = utils.make_toot(self.cfg) # generate a toot + toot = await utils.make_post(self.cfg) # generate a toot await self.pleroma.reply(notification['status'], toot, cw=self.cfg['cw']) @staticmethod def extract_toot(toot): - text = utils.extract_toot(toot) + text = utils.extract_post_content(toot) text = re.sub(r"^@\S+\s", r"", text) # remove the initial mention text = text.lower() # treat text as lowercase for easier keyword matching (if this bot uses it) return text