[FIX] mail: improve exception management when sending emails

Commit 00bd7274c4 introduced speed improvements when
sending emails through batching and reusing an SMTP connection for a
given batch.

However exception management was slightly changed during that patch.
Previously to this patch all errors in the sending process were considered
as MailDeliveryException, except for MemoryError and psycopg errors.
However now mail_mail.send() may raise another kind of exception in the
SMTP connect process. Moreover a raise_exception parameter allows to
choose to either raise an exception, or just set emails in exception
state without raising an error. However since the patch it is not taken
into account correctly.

This leads to several issues, notably

 * auth_signup waits for a MailDeliveryException when sending a password
   request email. A badly configured SMTP server leads to a connection
   error that is not caught. This prevents creating users, which could
   be annoying.
 * chatter does not handle exceptions as notification emails are sent
   using raise_exception being False. Having an issue in the connect
   process crashes the chatter.

This commit fixes the exception management so that it behaves like
before the patch.
This commit is contained in:
Thibault Delavallée
2017-03-16 10:06:24 +01:00
parent 6027e9370d
commit cee15f7d90
+8 -1
View File
@@ -210,7 +210,6 @@ class MailMail(models.Model):
for mail_batch in tools.split_every(batch_size, record_ids):
yield server_id, mail_batch
@api.multi
def send(self, auto_commit=False, raise_exception=False):
""" Sends the selected emails immediately, ignoring their current
@@ -231,6 +230,14 @@ class MailMail(models.Model):
smtp_session = None
try:
smtp_session = self.env['ir.mail_server'].connect(mail_server_id=server_id)
except Exception as exc:
if raise_exception:
# To be consistent and backward compatible with mail_mail.send() raised
# exceptions, it is encapsulated into an Odoo MailDeliveryException
raise MailDeliveryException(_('Unable to connect to SMTP Server'), exc)
else:
self.browse(batch_ids).write({'state': 'exception', 'failure_reason': exc})
else:
self.browse(batch_ids)._send(
auto_commit=auto_commit,
raise_exception=raise_exception,