From 4f19f2b4b4c038c7b6e557c5c114e5459da36898 Mon Sep 17 00:00:00 2001
From: Andrew Miller <amiller@dappervision.com>
Date: Sat, 31 Mar 2012 18:53:45 -0400
Subject: [PATCH] When the CLI cannot connect to the gateway, it prints an
 error message rather than raising a python exception. Includes a unit test

Signed-off-by: Andrew Miller <amiller@dappervision.com>
---
 src/allmydata/scripts/common_http.py | 12 ++++++++++--
 src/allmydata/test/test_cli.py       | 24 ++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/src/allmydata/scripts/common_http.py b/src/allmydata/scripts/common_http.py
index 66a6291c..7ffa41bd 100644
--- a/src/allmydata/scripts/common_http.py
+++ b/src/allmydata/scripts/common_http.py
@@ -6,7 +6,7 @@ import allmydata # for __full_version__
 
 from allmydata.util.encodingutil import quote_output
 from allmydata.scripts.common import TahoeError
-
+from socket import error as socket_error
 
 # copied from twisted/web/client.py
 def parse_url(url, defaultPort=None):
@@ -58,8 +58,16 @@ def do_http(method, url, body=""):
     length = body.tell()
     body.seek(old)
     c.putheader("Content-Length", str(length))
-    c.endheaders()
 
+    try:
+        c.endheaders()
+    except socket_error, err:
+        class BadResponse(object):
+            status=-1
+            reason="Error trying to connect to %s: %s" % (url, err)
+            read=lambda _: ""
+        return BadResponse()
+        
     while True:
         data = body.read(8192)
         if not data:
diff --git a/src/allmydata/test/test_cli.py b/src/allmydata/test/test_cli.py
index c88d00b3..e846a77a 100644
--- a/src/allmydata/test/test_cli.py
+++ b/src/allmydata/test/test_cli.py
@@ -13,6 +13,8 @@ from allmydata.immutable import upload
 from allmydata.interfaces import MDMF_VERSION, SDMF_VERSION
 from allmydata.mutable.publish import MutableData
 from allmydata.dirnode import normalize
+from allmydata.scripts.common_http import socket_error
+import allmydata.scripts.common_http
 from pycryptopp.publickey import ed25519
 
 # Test that the scripts can be imported.
@@ -3279,6 +3281,28 @@ class Errors(GridTestMixin, CLITestMixin, unittest.TestCase):
 
         return d
 
+    def test_broken_socket(self):
+        # When the http connection breaks (such as when node.url is overwritten
+        # by a confused user), a user friendly error message should be printed.
+        self.basedir = "cli/Errors/test_broken_socket"
+        self.set_up_grid()
+
+        # Simulate a connection error
+        endheaders = allmydata.scripts.common_http.httplib.HTTPConnection.endheaders
+        def _fix_endheaders(*args):
+            allmydata.scripts.common_http.httplib.HTTPConnection.endheaders = endheaders
+        def _socket_error(*args, **kwargs):
+            raise socket_error('test error')
+        allmydata.scripts.common_http.httplib.HTTPConnection.endheaders = _socket_error
+
+        d = self.do_cli("mkdir")
+        def _check_invalid((rc,stdout,stderr)):
+            self.failIfEqual(rc, 0)
+            self.failUnlessIn("Error trying to connect to http://127.0.0.1", stderr)
+        d.addCallback(_check_invalid)
+        d.addCallback(_fix_endheaders)
+        return d
+
 
 class Get(GridTestMixin, CLITestMixin, unittest.TestCase):
     def test_get_without_alias(self):
-- 
2.45.2