From 466619f6356f9f7e24ae1b43520eddae6520ea82 Mon Sep 17 00:00:00 2001 From: Paul Baranay Date: Tue, 26 Sep 2017 18:26:11 -0400 Subject: [PATCH] Save exception message when Notification breaks --- tests/test/tests/test_models.py | 24 +++++++++++++++++++ tests/test/tests/test_tasks.py | 6 +++-- transmissions/admin.py | 9 +++---- .../migrations/0005_notification_exception.py | 20 ++++++++++++++++ transmissions/models.py | 5 +++- 5 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 transmissions/migrations/0005_notification_exception.py diff --git a/tests/test/tests/test_models.py b/tests/test/tests/test_models.py index 9995c7f..3a5a1cb 100644 --- a/tests/test/tests/test_models.py +++ b/tests/test/tests/test_models.py @@ -39,6 +39,15 @@ class TriggerOncePerContentMessage(DefaultEmailMessage): class TriggerDeleteAfterMessage(DefaultEmailMessage): template_name = 'test' +TRIGGER_BROKEN = 'trigger_broken' +@message(TRIGGER_BROKEN) +class BrokenMessage(DefaultEmailMessage): + template_name = 'test' + + def __init__(self, notification): + super(BrokenMessage, self).__init__(notification) + raise ValueError('This message is broken at init') + class ModelTests(TestCase): def setUp(self): @@ -236,3 +245,18 @@ def test_invalid_data(self): self.assertEqual(notification.status, Notification.Status.BROKEN) self.assertEqual(notification.data, '{}') + def test_broken(self): + + welcome_path = "{}.{}".format(SimpleMessage.__module__, SimpleMessage.__name__) + trigger_settings = {TRIGGER_BROKEN: welcome_path} + with self.settings(TRANSMISSIONS_TRIGGERS=trigger_settings): + + user = factories.User() + + notification = BrokenMessage.trigger(user) + + with self.assertRaises(ValueError): + notification.send() + + self.assertEqual(notification.status, Notification.Status.BROKEN) + self.assertEqual(notification.exception, "ValueError: This message is broken at init") diff --git a/tests/test/tests/test_tasks.py b/tests/test/tests/test_tasks.py index e34e359..7ad24ee 100644 --- a/tests/test/tests/test_tasks.py +++ b/tests/test/tests/test_tasks.py @@ -17,6 +17,7 @@ TRIGGER_NAME = 'task_test' TRIGGER_SUBJECT = 'This is a task test' +EXCEPTION_MESSAGE = 'This message is broken at init' @message(TRIGGER_NAME, behavior=None, subject=TRIGGER_SUBJECT) class TaskTestMessage(DefaultEmailMessage): @@ -29,7 +30,7 @@ class BrokenMessage(DefaultEmailMessage): def __init__(self, notification): super(BrokenMessage, self).__init__(notification) - raise Exception('This message is broken at init') + raise Exception(EXCEPTION_MESSAGE) class TasksTests(TestCase): @@ -238,7 +239,7 @@ def test_process_broken(self): self.assertEqual(notification.status, Notification.Status.CREATED) # Trigger single task - with self.assertRaisesMessage(Exception, 'This message is broken at init'): + with self.assertRaisesMessage(Exception, EXCEPTION_MESSAGE): tasks.process_all_notifications() notification = Notification.objects.get(pk=notification.id) @@ -249,6 +250,7 @@ def test_process_broken(self): # Check status self.assertEqual(notification.status, Notification.Status.BROKEN) self.assertGreaterEqual(notification.datetime_processed, notification.datetime_scheduled) + self.assertEqual(notification.exception, "Exception: {}".format(EXCEPTION_MESSAGE)) # Check email was sent self.assertEqual(len(mail.outbox), 0) \ No newline at end of file diff --git a/transmissions/admin.py b/transmissions/admin.py index 44bc25c..40e7ea1 100644 --- a/transmissions/admin.py +++ b/transmissions/admin.py @@ -38,20 +38,21 @@ class NotificationAdmin(admin.ModelAdmin): 'status', 'datetime_created', 'datetime_scheduled', - 'datetime_processed' + 'datetime_processed', + 'exception', ] search_fields = ['=id', 'target_user__email'] readonly_fields = ['id', 'trigger_name', _link_to_target_user, _link_to_trigger_user, 'datetime_created', - 'datetime_processed', 'datetime_seen', 'datetime_consumed', 'content'] + 'datetime_processed', 'datetime_seen', 'datetime_consumed', 'exception', 'content'] fieldsets = (('Notifications', {'fields': ('id', _link_to_target_user, 'trigger_name')}), ('Status', {'fields': ( 'status', _link_to_trigger_user, 'datetime_created', 'datetime_scheduled', 'datetime_processed', - 'datetime_seen', 'datetime_consumed')}), + 'datetime_seen', 'datetime_consumed', 'exception')}), ('Content', {'fields': ('content',)}) ) -admin.site.register(Notification, NotificationAdmin) \ No newline at end of file +admin.site.register(Notification, NotificationAdmin) diff --git a/transmissions/migrations/0005_notification_exception.py b/transmissions/migrations/0005_notification_exception.py new file mode 100644 index 0000000..767dd2b --- /dev/null +++ b/transmissions/migrations/0005_notification_exception.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.10 on 2017-09-26 22:29 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('transmissions', '0004_auto_20161027_1149'), + ] + + operations = [ + migrations.AddField( + model_name='notification', + name='exception', + field=models.TextField(blank=True, default=b''), + ), + ] diff --git a/transmissions/models.py b/transmissions/models.py index 478e422..90ad6dd 100644 --- a/transmissions/models.py +++ b/transmissions/models.py @@ -85,6 +85,8 @@ class Status(EnumDict): status = models.IntegerField(default=Status.CREATED) + exception = models.TextField(blank=True, default='') + @property def data(self): if not hasattr(self, '_data'): @@ -120,8 +122,9 @@ def send(self): self.delete() except ChannelSendException: self.status = self.Status.FAILED - except: + except Exception as e: self.status = self.Status.BROKEN + self.exception = "{klass}: {message}".format(klass=e.__class__.__name__, message=str(e)) raise finally: if self.pk: