[#8430] connect more proactively; retry only certain SMTP failures
diff --git a/Allura/allura/lib/mail_util.py b/Allura/allura/lib/mail_util.py
index 67808b7..374cb25 100644
--- a/Allura/allura/lib/mail_util.py
+++ b/Allura/allura/lib/mail_util.py
@@ -301,12 +301,25 @@
log.warning('No valid addrs in %s, so not sending mail',
list(map(str, addrs)))
return
+ if not self._client:
+ self._connect()
try:
self._client.sendmail(
config.return_path,
smtp_addrs,
content)
- except Exception:
+ need_retry = False
+ except (smtplib.SMTPServerDisconnected, smtplib.SMTPConnectError) as e:
+ log.info(f'will retry after getting this smtp error: {e!r}')
+ need_retry = True
+ except smtplib.SMTPResponseException as e:
+ if 400 <= e.smtp_code < 500: # 4__ is "Transient Negative"
+ log.info(f'will retry after getting this smtp error: {e!r}')
+ need_retry = True
+ else:
+ raise
+ if need_retry:
+ # maybe could sleep? or if we're in a task, reschedule it somehow?
self._connect()
self._client.sendmail(
config.return_path,
@@ -314,6 +327,7 @@
content)
def _connect(self):
+ log.info('connecting to SMTP server')
if asbool(tg.config.get('smtp_ssl', False)):
smtp_client = smtplib.SMTP_SSL(
tg.config.get('smtp_server', 'localhost'),
@@ -327,6 +341,7 @@
timeout=float(tg.config.get('smtp_timeout', 10)),
)
if tg.config.get('smtp_user', None):
+ log.info('authenticating to SMTP server')
smtp_client.login(tg.config['smtp_user'],
tg.config['smtp_password'])
if asbool(tg.config.get('smtp_tls', False)):