mercurial/url.py
changeset 40018 f80db6adabbe
parent 37735 126998dcfb08
child 40031 f2dffa1359c6
--- a/mercurial/url.py	Wed Sep 26 14:54:15 2018 -0700
+++ b/mercurial/url.py	Wed Sep 26 16:07:59 2018 -0700
@@ -595,3 +595,39 @@
         url_ = 'file://' + pycompat.bytesurl(urlreq.pathname2url(path))
         authinfo = None
     return opener(ui, authinfo).open(pycompat.strurl(url_), data)
+
+def wrapresponse(resp):
+    """Wrap a response object with common error handlers.
+
+    This ensures that any I/O from any consumer raises the appropriate
+    error and messaging.
+    """
+    origread = resp.read
+
+    class readerproxy(resp.__class__):
+        def read(self, size=None):
+            try:
+                return origread(size)
+            except httplib.IncompleteRead as e:
+                # e.expected is an integer if length known or None otherwise.
+                if e.expected:
+                    got = len(e.partial)
+                    total = e.expected + got
+                    msg = _('HTTP request error (incomplete response; '
+                            'expected %d bytes got %d)') % (total, got)
+                else:
+                    msg = _('HTTP request error (incomplete response)')
+
+                raise error.PeerTransportError(
+                    msg,
+                    hint=_('this may be an intermittent network failure; '
+                           'if the error persists, consider contacting the '
+                           'network or server operator'))
+            except httplib.HTTPException as e:
+                raise error.PeerTransportError(
+                    _('HTTP request error (%s)') % e,
+                    hint=_('this may be an intermittent network failure; '
+                           'if the error persists, consider contacting the '
+                           'network or server operator'))
+
+    resp.__class__ = readerproxy