diff -ur Trac-1.4.3.orig/trac/notification/api.py Trac-1.4.3/trac/notification/api.py --- Trac-1.4.3.orig/trac/notification/api.py 2021-05-10 07:14:13.000000000 +0900 +++ Trac-1.4.3/trac/notification/api.py 2023-01-16 18:26:51.804001854 +0900 @@ -23,6 +23,7 @@ ListOption, Option) from trac.core import Component, Interface, ExtensionPoint from trac.util import as_bool, lazy, to_list +from trac.util.text import exception_to_unicode __all__ = ['IEmailAddressResolver', 'IEmailDecorator', 'IEmailSender', @@ -209,6 +210,11 @@ self.time = time self.author = author + def __repr__(self): + return '<%s realm=%r, category=%r, target=%r, time=%r, author=%r>' % \ + (self.__class__.__name__, self.realm, self.category, + self.target, self.time, self.author) + class NotificationSystem(Component): @@ -370,7 +376,12 @@ :param event: a `NotificationEvent` """ - self.distribute_event(event, self.subscriptions(event)) + try: + self.distribute_event(event, self.subscriptions(event)) + except Exception as e: + self.log.error("Failure distributing event %r%s", event, + exception_to_unicode(e, traceback=True)) + raise def distribute_event(self, event, subscriptions): """Distribute a event to all subscriptions. diff -ur Trac-1.4.3.orig/trac/ticket/notification.py Trac-1.4.3/trac/ticket/notification.py --- Trac-1.4.3.orig/trac/ticket/notification.py 2021-05-10 07:14:13.000000000 +0900 +++ Trac-1.4.3/trac/ticket/notification.py 2023-01-16 18:26:59.340082792 +0900 @@ -690,6 +690,14 @@ # Harvest previous CC field if 'fields' in event.changes and 'cc' in event.changes['fields']: cc_users.update(to_set(event.changes['fields']['cc']['old'])) + + # Get members of permission groups + groups = PermissionSystem(self.env).get_groups_dict() + for cc in sorted(cc_users): + if cc in groups: + cc_users.discard(cc) + cc_users.update(groups[cc]) + return _ticket_change_subscribers(self, cc_users) def description(self): @@ -751,13 +759,6 @@ if not isinstance(candidates, (list, set, tuple)): candidates = [candidates] - # Get members of permission groups - groups = PermissionSystem(subscriber.env).get_groups_dict() - for cc in set(candidates): - if cc in groups: - candidates.remove(cc) - candidates.update(groups[cc]) - matcher = RecipientMatcher(subscriber.env) klass = subscriber.__class__.__name__ sids = set()