diff --git a/django/core/mail/backends/smtp.py b/django/core/mail/backends/smtp.py index b6f7f560ed6..baffa8f2dfb 100644 --- a/django/core/mail/backends/smtp.py +++ b/django/core/mail/backends/smtp.py @@ -63,9 +63,10 @@ class EmailBackend(BaseEmailBackend): try: try: self.connection.quit() - except socket.sslerror: + except (socket.sslerror, smtplib.SMTPServerDisconnected): # This happens when calling quit() on a TLS connection - # sometimes. + # sometimes, or when the connection was already disconnected + # by the server. self.connection.close() except: if self.fail_silently: diff --git a/tests/regressiontests/mail/tests.py b/tests/regressiontests/mail/tests.py index a8fbf20fd60..9ab8c2c301f 100644 --- a/tests/regressiontests/mail/tests.py +++ b/tests/regressiontests/mail/tests.py @@ -659,9 +659,9 @@ class FakeSMTPServer(smtpd.SMTPServer, threading.Thread): asyncore.close_all() def stop(self): - assert self.active - self.active = False - self.join() + if self.active: + self.active = False + self.join() class SMTPBackendTests(BaseEmailBackendTests, TestCase): @@ -715,3 +715,16 @@ class SMTPBackendTests(BaseEmailBackendTests, TestCase): backend = smtp.EmailBackend(username='', password='') self.assertEqual(backend.username, '') self.assertEqual(backend.password, '') + + def test_server_stopped(self): + """ + Test that closing the backend while the SMTP server is stopped doesn't + raise an exception. + """ + backend = smtp.EmailBackend(username='', password='') + backend.open() + self.server.stop() + try: + backend.close() + except Exception as e: + self.fail("close() unexpectedly raised an exception: %s" % e)