diff --git a/osf/models/notification_type.py b/osf/models/notification_type.py index ea41262a52a..fbbe2524f99 100644 --- a/osf/models/notification_type.py +++ b/osf/models/notification_type.py @@ -5,6 +5,7 @@ from website import settings from enum import Enum from osf.utils.caching import ttl_cached_property +from framework import sentry def get_default_frequency_choices(): @@ -222,14 +223,31 @@ def emit( _is_digest=is_digest, ) else: - subscription, created = NotificationSubscription.objects.get_or_create( - notification_type=self, - user=user, - content_type=content_type, - object_id=subscribed_object.pk if subscribed_object else None, - defaults={'message_frequency': message_frequency}, - _is_digest=is_digest, - ) + try: + subscription, created = NotificationSubscription.objects.get_or_create( + notification_type=self, + user=user, + content_type=content_type, + object_id=subscribed_object.pk if subscribed_object else None, + defaults={'message_frequency': message_frequency}, + _is_digest=is_digest, + ) + except NotificationSubscription.MultipleObjectsReturned as e: + # Temporary fix before we deduplicate and add constraints: use the last created one if duplicates found + subscriptions_qs = NotificationSubscription.objects.filter( + notification_type=self, + user=user, + content_type=content_type, + object_id=subscribed_object.pk if subscribed_object else None, + defaults={'message_frequency': message_frequency}, + _is_digest=is_digest, + ).order_by('id') + sentry.log_exception(e) + count = subscriptions_qs.count() + subscription = subscriptions_qs.last() + sentry.log_message(f'Multiple notification subscriptions found, using the last created one: ' + f'[count={count}, user={user._id}, type={self.name}, last={subscription.id}]') + subscription.emit( destination_address=destination_address, event_context=event_context,