11import sys
2+ import traceback
23
34from datetime import datetime
45
56from django .core import mail
67from entity_event import context_loader
78
89from entity_emailer .models import Email
9- from entity_emailer .signals import pre_send
10+ from entity_emailer .signals import pre_send , email_exception
1011
1112from entity_emailer .utils import get_medium , get_from_email_address , get_subscribed_email_addresses , \
1213 create_email_message , extract_email_subject_from_html_content
@@ -23,6 +24,7 @@ def send_unsent_scheduled_emails():
2324 Send out any scheduled emails that are unsent
2425 """
2526
27+ # Get the emails that we need to send
2628 current_time = datetime .utcnow ()
2729 email_medium = get_medium ()
2830 to_send = Email .objects .filter (
@@ -32,15 +34,30 @@ def send_unsent_scheduled_emails():
3234 'event__source'
3335 ).prefetch_related (
3436 'recipients'
37+ ).order_by (
38+ 'scheduled' ,
39+ 'id'
3540 )
3641
3742 # Fetch the contexts of every event so that they may be rendered
3843 context_loader .load_contexts_and_renderers ([e .event for e in to_send ], [email_medium ])
3944
45+ # Keep track of what emails we will be sending
4046 emails = []
47+
48+ # Loop over each email and generate the recipients, and message
49+ # and handle any exceptions that may occur
4150 for email in to_send :
51+ # Compute what email addresses we actually want to send this email to
4252 to_email_addresses = get_subscribed_email_addresses (email )
43- if to_email_addresses :
53+
54+ # If there are no recipients we can just skip rendering
55+ if not to_email_addresses :
56+ continue
57+
58+ # If any exceptions occur we will catch the exception and store it as a reference
59+ # As well as fire off a signal with the error and mark the email as sent and errored
60+ try :
4461 # Render the email
4562 text_message , html_message = email .render (email_medium )
4663
@@ -64,9 +81,23 @@ def send_unsent_scheduled_emails():
6481
6582 # Add the email to the list of emails that need to be sent
6683 emails .append (message )
84+ except Exception as e :
85+ # Save the exception on the model
86+ email .exception = traceback .format_exc ()
87+ email .save (update_fields = ['exception' ])
88+
89+ # Fire the email exception event
90+ email_exception .send (
91+ sender = Email ,
92+ email = email ,
93+ exception = e
94+ )
6795
96+ # Send all the emails that were generated properly
6897 connection = mail .get_connection ()
6998 connection .send_messages (emails )
99+
100+ # Update the emails as sent
70101 to_send .update (sent = current_time )
71102
72103 @staticmethod
0 commit comments