diff --git a/docs/sending/exceptions.rst b/docs/sending/exceptions.rst index 6a01b96..ffb08ae 100644 --- a/docs/sending/exceptions.rst +++ b/docs/sending/exceptions.rst @@ -35,6 +35,11 @@ Exceptions help explain what went wrong. (Tip: you may also be able to check the API log in your ESP's dashboard. See :ref:`troubleshooting`.) + In production, it's not unusual for sends to occasionally fail due to transient + connectivity problems, ESP maintenance, or other operational issues. Typically + these failures have a 5xx :attr:`status_code`. See :ref:`transient-errors` + for suggestions on retrying these failed sends. + .. exception:: AnymailInvalidAddress diff --git a/docs/tips/index.rst b/docs/tips/index.rst index e97a53f..c09723a 100644 --- a/docs/tips/index.rst +++ b/docs/tips/index.rst @@ -7,6 +7,7 @@ done with Anymail: .. toctree:: :maxdepth: 1 + transient_errors multiple_backends django_templates securing_webhooks diff --git a/docs/tips/transient_errors.rst b/docs/tips/transient_errors.rst new file mode 100644 index 0000000..ad2f15a --- /dev/null +++ b/docs/tips/transient_errors.rst @@ -0,0 +1,25 @@ +.. _transient-errors: + +Handling transient errors +========================= + +Applications using Anymail need to be prepared to deal with connectivity issues +and other transient errors from your ESP's API (as with any networked API). + +Because Django doesn't have a built-in way to say "try this again in a few moments," +Anymail doesn't have its own logic to retry network errors. The best way to handle +transient ESP errors depends on your Django project: + +* If you already use something like :pypi:`celery` or :pypi:`Django channels ` + for background task scheduling, that's usually the best choice for handling Anymail sends. + Queue a task for every send, and wait to mark the task complete until the send succeeds + (or repeatedly fails, according to whatever logic makes sense for your app). + +* Another option is the Pinax :pypi:`django-mailer` package, which queues and automatically + retries failed sends for any Django EmailBackend, including Anymail. django-mailer maintains + its send queue in your regular Django DB, which is a simple way to get started but may not + scale well for very large volumes of outbound email. + +In addition to handling connectivity issues, either of these approaches also has the advantage +of moving email sending to a background thread. This is a best practice for sending email from +Django, as it allows your web views to respond faster.