Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up send error handling; fix stalled send queue. #78

Closed
wants to merge 1 commit into from

Conversation

medmunds
Copy link
Contributor

[NOT FOR MERGE yet: see "TODO" comments for discussion]

In engine.send_all:

  • Handle transient connection issues by logging failure
    and cleanly exiting send_all. (Previously, crashed
    without logging.)
  • Handle all other smtplib.SMTPException by deferring
    message. (Previously, behavior differed between
    Python 2 and 3.)
  • Handle all other exceptions by logging error with new
    RESULT_ERROR status, and deleting message from send
    queue. (Previously, crashed without logging, leaving
    possibly-unsendable message blocking send queue.)

Potentially-breaking change: If you are using a
MAILER_EMAIL_BACKEND other than the default
SMTP EmailBackend, errors from that backend may
be handled differently now.

Addresses #73. (And additional discussion there.)

[NOT FOR MERGE yet: see "TODO" comments for discussion]

In engine.send_all:

* Handle transient connection issues by logging failure
  and cleanly exiting send_all. (Previously, crashed
  without logging.)
* Handle all other smtplib.SMTPException by deferring
  message. (Previously, behavior differed between
  Python 2 and 3.)
* Handle all other exceptions by logging error with new
  RESULT_ERROR status and deleting message from send
  queue. (Previously, crashed without logging, leaving
  possibly-unsendable message blocking send queue.)

**Potentially-breaking change:** If you are using a
MAILER_EMAIL_BACKEND other than the default
SMTP EmailBackend, errors from that backend *may*
be handled differently now.

Addresses pinax#73. (And additional discussion there.)
@coveralls
Copy link

coveralls commented Dec 10, 2016

Coverage Status

Coverage increased (+0.3%) to 87.083% when pulling 65fbb75 on medmunds:pr_send_error_handling into f6bc3fd on pinax:master.

@spookylukey
Copy link
Contributor

Some initial feedback:

First, thanks so much for digging into this thorny issue! The approach seems pretty good to me.

Some things to tweak:

  1. For logging, we should be using warn for transient errors (where we are going to retry), and error for permanent errors.

  2. For messages that failed to send and were deleted from the queue, it would be nice if they could be seen easily by staff. Is it the case that the Django admin for MessageLog allows them to be seen easily? Perhaps we should also have a 'retry' action that will resurrect a Message from a MessageLog, but that's out of scope for this issue.

@@ -103,7 +102,7 @@ def release_lock(lock):
logging.debug("released.")


def send_all():
def send_all(): # noqa: C901 # TODO: refactor to reduce complexity
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm personally not that worried about complexity here - I don't think clarity would be increased that much by refactoring it.

@taleinat
Copy link

This looks good to me.

message.defer()
logging.info("message deferred due to failure: %s" % err)
MessageLog.objects.log(message, RESULT_FAILURE, log_message=str(err))
deferred += 1
# Get new connection, it case the connection itself has an error.
connection = None

except Exception as err:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New to the party but why are you deleting these instead of deferring them too? Seems like a harsh thing to force on people not using SMTPlibs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the "deferring permanent errors isn't helpful, and can lead to other problems" case discussed in #73. IIRC, one of the reasons I didn't follow through with this PR is that it's not at all clear how to reliably distinguish "transient error, should defer and retry later" from "permanent error, retry won't be helpful". More discussion in #73.

If you have an idea for an approach that would work well with a variety of email backends, it'd be awesome to have someone adopt this PR and drive it to completion.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, missed the "other problems" and that is indeed a concern. Thanks for the update, I had read that you were stepping away from the project so I appreciate the comment.

@medmunds
Copy link
Contributor Author

To avoid confusion, I'm closing this PR, since I'm not going to be able to resolve the various issues it raises. It's linked in the original issue #73, and if someone wants to grab the code and resurrect it later that would be great.

@medmunds medmunds closed this Oct 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants