-
Hi, thank you for this project it saved me a lot of time! My function sends an e-mail: from django.core.mail import EmailMessage
def dummy():
email = EmailMessage(
"subject",
"body",
"from@example.com"
["to@example.com"],
)
email.send() Is there any general way to catch the exception from email backends other than using broad This would mean that for each email backend I'd have to add its exception in the test:
I noticed there was once a proposal for this https://code.djangoproject.com/ticket/23944 Thank you. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
The answer kind of depends on why you're catching the error and what you want to do with it—the specifics of the "do something useful" in your example. If you're trying to do some generic handling—say, logging the error for later investigation—then catching the broad For pretty much anything else, "do something useful" probably involves digging into the details of the error. And that's going to be specific to the email backend and even the particular ESP. For example, you might want to handle a temporary ESP outage by quietly queuing the email to re-send later. But if the error is your API keys are invalid, you'd probably want to handle that with a loud, urgent operational alert. Distinguishing those cases requires examining attributes of the error itself, which will differ between backends and ESPs. try:
email.send()
except AnymailError as err:
# (not all AnymailErrors include an API HTTP status_code)
status_code = getattr(err, 'status_code', None)
if 500 <= status_code < 600 or status_code == 429:
# network error or API rate limit
queue_email_for_later_retry(email)
else:
# some other problem; let logging report the error to us
raise
except smtplib.SMTPException as err:
if nontrivial_logic_to_recognize_retryable_smtp_error(err):
queue_email_for_later_retry(email)
else:
raise
# ... etc. ... I'd be very open to proposals to normalize some of the ESP-specific sending error logic in Anymail. In particular, introducing a way to distinguish transient sending problems (where re-sending the same message later may succeed) to more permanent errors like invalid addresses or sending options. (Incidentally, the django-mailer project ran into a similar issue. After a multi-year discussion, I believe they came to the conclusion that there isn't a good generic error handling solution across multiple email backends, and ended up adding a user-overridable error handler instead.) |
Beta Was this translation helpful? Give feedback.
The answer kind of depends on why you're catching the error and what you want to do with it—the specifics of the "do something useful" in your example.
If you're trying to do some generic handling—say, logging the error for later investigation—then catching the broad
Exception
seems fine. (It's what Django core contributor Tim Graham suggested in closing the Django ticket you found.)For pretty much anything else, "do something useful" probably involves digging into the details of the error. And that's going to be specific to the email backend and even the particular ESP. For example, you might want to handle a temporary ESP outage by quietly queuing the email to re-send later. But if the…