From 919b166241ee1b9b2193265d4a07f75e27096982 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Mar 2021 08:13:20 -0800 Subject: [PATCH] Catch error in serializing unknown boosts --- bookwyrm/activitypub/base_activity.py | 5 ++--- bookwyrm/connectors/abstract_connector.py | 2 +- bookwyrm/models/status.py | 9 +++++++-- bookwyrm/tests/models/test_status_model.py | 16 +++++++++++++++- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/bookwyrm/activitypub/base_activity.py b/bookwyrm/activitypub/base_activity.py index 315ff58c..170bdfb9 100644 --- a/bookwyrm/activitypub/base_activity.py +++ b/bookwyrm/activitypub/base_activity.py @@ -258,10 +258,9 @@ def resolve_remote_id(remote_id, model=None, refresh=False, save=True): # load the data and create the object try: data = get_data(remote_id) - except (ConnectorException, ConnectionError): + except ConnectorException: raise ActivitySerializerError( - "Could not connect to host for remote_id in %s model: %s" - % (model.__name__, remote_id) + "Could not connect to host for remote_id in: %s" % (remote_id) ) # determine the model implicitly, if not provided if not model: diff --git a/bookwyrm/connectors/abstract_connector.py b/bookwyrm/connectors/abstract_connector.py index 9f31b337..3ebedf65 100644 --- a/bookwyrm/connectors/abstract_connector.py +++ b/bookwyrm/connectors/abstract_connector.py @@ -244,7 +244,7 @@ def get_data(url): "User-Agent": settings.USER_AGENT, }, ) - except (RequestError, SSLError) as e: + except (RequestError, SSLError, ConnectionError) as e: logger.exception(e) raise ConnectorException() diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index 80f2b593..c5e69936 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -115,13 +115,18 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): def ignore_activity(cls, activity): """ keep notes if they are replies to existing statuses """ if activity.type == "Announce": - # keep it if the booster or the boosted are local - boosted = activitypub.resolve_remote_id(activity.object, save=False) + try: + boosted = activitypub.resolve_remote_id(activity.object, save=False) + except activitypub.ActivitySerializerError: + # if we can't load the status, definitely ignore it + return True + # keep the boost if we would keep the status return cls.ignore_activity(boosted.to_activity_dataclass()) # keep if it if it's a custom type if activity.type != "Note": return False + # keep it if it's a reply to an existing status if cls.objects.filter(remote_id=activity.inReplyTo).exists(): return False diff --git a/bookwyrm/tests/models/test_status_model.py b/bookwyrm/tests/models/test_status_model.py index ddc92d36..b2ee69b8 100644 --- a/bookwyrm/tests/models/test_status_model.py +++ b/bookwyrm/tests/models/test_status_model.py @@ -8,8 +8,9 @@ from django.core.files.base import ContentFile from django.db import IntegrityError from django.test import TestCase from django.utils import timezone +import responses -from bookwyrm import models, settings +from bookwyrm import activitypub, models, settings # pylint: disable=too-many-public-methods @@ -385,3 +386,16 @@ class Status(TestCase): status.mention_users.set([self.remote_user]) self.assertEqual(status.recipients, [self.remote_user]) + + @responses.activate + def test_ignore_activity_boost(self, _): + """ don't bother with most remote statuses """ + activity = activitypub.Announce( + id="http://www.faraway.com/boost/12", + actor=self.remote_user.remote_id, + object="http://fish.com/nothing", + ) + + responses.add(responses.GET, "http://fish.com/nothing", status=404) + + self.assertTrue(models.Status.ignore_activity(activity))