Rev 2696: Make error handling nicer when SMTP server not working in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Mon Aug 13 13:24:46 BST 2007


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 2696
revision-id: pqm at pqm.ubuntu.com-20070813122444-5pi8f4fwxqpgxs1x
parent: pqm at pqm.ubuntu.com-20070810230629-bcp0rgmbhp0z35e1
parent: abentley at panoramicfeedback.com-20070810161955-s3t2n8j6vn2ypff7
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Mon 2007-08-13 13:24:44 +0100
message:
  Make error handling nicer when SMTP server not working
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
  bzrlib/smtp_connection.py      smtp_connection.py-20070618204456-nu6wag1ste4biuk2-1
  bzrlib/tests/test_smtp_connection.py test_smtp_connection-20070618204509-wuyxc0r0ztrecv7e-1
    ------------------------------------------------------------
    revno: 2694.2.2
    merged: abentley at panoramicfeedback.com-20070810161955-s3t2n8j6vn2ypff7
    parent: abentley at panoramicfeedback.com-20070810161730-fda8tva0jxraklk4
    committer: Aaron Bentley <abentley at panoramicfeedback.com>
    branch nick: no-local-smtp
    timestamp: Fri 2007-08-10 12:19:55 -0400
    message:
      Update NEWS
    ------------------------------------------------------------
    revno: 2694.2.1
    merged: abentley at panoramicfeedback.com-20070810161730-fda8tva0jxraklk4
    parent: pqm at pqm.ubuntu.com-20070810111627-h6m8b0ist3ca15ae
    committer: Aaron Bentley <abentley at panoramicfeedback.com>
    branch nick: no-local-smtp
    timestamp: Fri 2007-08-10 12:17:30 -0400
    message:
      Make error handling nicer when SMTP server not working
=== modified file 'NEWS'
--- a/NEWS	2007-08-10 10:00:53 +0000
+++ b/NEWS	2007-08-10 16:19:55 +0000
@@ -41,6 +41,9 @@
     * Graph._filter_candidate_lca does not raise KeyError if a candidate
       is eliminated just before it would normally be examined.  (Aaron Bentley)
 
+    * SMTP connection failures produce a nice message, not a traceback.
+      (Aaron Bentley)
+
   IMPROVEMENTS:
 
     * Don't show "dots" progress indicators when run non-interactively, such

=== modified file 'bzrlib/errors.py'
--- a/bzrlib/errors.py	2007-07-20 18:59:29 +0000
+++ b/bzrlib/errors.py	2007-08-10 16:17:30 +0000
@@ -2308,3 +2308,17 @@
 
     def __init__(self, error):
         self.error = error
+
+
+class SMTPConnectionRefused(SMTPError):
+
+    _fmt = "SMTP connection to %(host)s refused"
+
+    def __init__(self, error, host):
+        self.error = error
+        self.host = host
+
+
+class DefaultSMTPConnectionRefused(SMTPConnectionRefused):
+
+    _fmt = "Please specify smtp_server.  No server at default %(host)s."

=== modified file 'bzrlib/smtp_connection.py'
--- a/bzrlib/smtp_connection.py	2007-07-18 15:51:52 +0000
+++ b/bzrlib/smtp_connection.py	2007-08-10 16:17:30 +0000
@@ -17,10 +17,17 @@
 """A convenience class around smtplib."""
 
 from email import Utils
+import errno
 import smtplib
+import socket
 
 from bzrlib import ui
-from bzrlib.errors import NoDestinationAddress, SMTPError
+from bzrlib.errors import (
+    NoDestinationAddress,
+    SMTPError,
+    DefaultSMTPConnectionRefused,
+    SMTPConnectionRefused,
+    )
 
 
 class SMTPConnection(object):
@@ -33,9 +40,13 @@
 
     _default_smtp_server = 'localhost'
 
-    def __init__(self, config):
+    def __init__(self, config, _smtp_factory=None):
+        self._smtp_factory = _smtp_factory
+        if self._smtp_factory is None:
+            self._smtp_factory = smtplib.SMTP
         self._config = config
-        self._smtp_server = config.get_user_option('smtp_server')
+        self._config_smtp_server = config.get_user_option('smtp_server')
+        self._smtp_server = self._config_smtp_server
         if self._smtp_server is None:
             self._smtp_server = self._default_smtp_server
 
@@ -54,8 +65,19 @@
 
     def _create_connection(self):
         """Create an SMTP connection."""
-        self._connection = smtplib.SMTP()
-        self._connection.connect(self._smtp_server)
+        self._connection = self._smtp_factory()
+        try:
+            self._connection.connect(self._smtp_server)
+        except socket.error, e:
+            if e.args[0] == errno.ECONNREFUSED:
+                if self._config_smtp_server is None:
+                    raise DefaultSMTPConnectionRefused(socket.error,
+                                                       self._smtp_server)
+                else:
+                    raise SMTPConnectionRefused(socket.error,
+                                                self._smtp_server)
+            else:
+                raise
 
         # If this fails, it just returns an error, but it shouldn't raise an
         # exception unless something goes really wrong (in which case we want

=== modified file 'bzrlib/tests/test_smtp_connection.py'
--- a/bzrlib/tests/test_smtp_connection.py	2007-07-18 15:51:52 +0000
+++ b/bzrlib/tests/test_smtp_connection.py	2007-08-10 16:17:30 +0000
@@ -16,21 +16,35 @@
 
 from cStringIO import StringIO
 from email.Message import Message
+import errno
+import smtplib
+import socket
 
-from bzrlib import config
+from bzrlib import (
+    config,
+    errors,
+    )
 from bzrlib.email_message import EmailMessage
 from bzrlib.errors import NoDestinationAddress
 from bzrlib.tests import TestCase
 from bzrlib.smtp_connection import SMTPConnection
 
 
+def connection_refuser():
+    def connect(server):
+        raise socket.error(errno.ECONNREFUSED, 'Connection Refused')
+    smtp = smtplib.SMTP()
+    smtp.connect = connect
+    return smtp
+
+
 class TestSMTPConnection(TestCase):
 
-    def get_connection(self, text):
+    def get_connection(self, text, smtp_factory=None):
         my_config = config.GlobalConfig()
         config_file = StringIO(text)
         my_config._get_parser(config_file)
-        return SMTPConnection(my_config)
+        return SMTPConnection(my_config, _smtp_factory=smtp_factory)
 
     def test_defaults(self):
         conn = self.get_connection('')
@@ -42,6 +56,13 @@
         conn = self.get_connection('[DEFAULT]\nsmtp_server=host:10\n')
         self.assertEqual('host:10', conn._smtp_server)
 
+    def test_missing_server(self):
+        conn = self.get_connection('', smtp_factory=connection_refuser)
+        self.assertRaises(errors.DefaultSMTPConnectionRefused, conn._connect)
+        conn = self.get_connection('[DEFAULT]\nsmtp_server=smtp.example.com\n',
+                                   smtp_factory=connection_refuser)
+        self.assertRaises(errors.SMTPConnectionRefused, conn._connect)
+
     def test_smtp_username(self):
         conn = self.get_connection('')
         self.assertIs(None, conn._smtp_username)




More information about the bazaar-commits mailing list