##// END OF EJS Templates
httppeer: wrap HTTPResponse.read() globally...
Gregory Szorc -
r32002:bf855efe default
parent child Browse files
Show More
@@ -252,3 +252,6 class UnsupportedBundleSpecification(Exc
252
252
253 class CorruptedState(Exception):
253 class CorruptedState(Exception):
254 """error raised when a command is not able to read its state from file"""
254 """error raised when a command is not able to read its state from file"""
255
256 class RichIOError(Abort):
257 """An IOError that can also have a hint attached."""
@@ -75,6 +75,41 def encodevalueinheaders(value, header,
75
75
76 return result
76 return result
77
77
78 def _wraphttpresponse(resp):
79 """Wrap an HTTPResponse with common error handlers.
80
81 This ensures that any I/O from any consumer raises the appropriate
82 error and messaging.
83 """
84 origread = resp.read
85
86 class readerproxy(resp.__class__):
87 def read(self, size=None):
88 try:
89 return origread(size)
90 except httplib.IncompleteRead as e:
91 # e.expected is an integer if length known or None otherwise.
92 if e.expected:
93 msg = _('HTTP request error (incomplete response; '
94 'expected %d bytes got %d)') % (e.expected,
95 len(e.partial))
96 else:
97 msg = _('HTTP request error (incomplete response)')
98
99 raise error.RichIOError(
100 msg,
101 hint=_('this may be an intermittent network failure; '
102 'if the error persists, consider contacting the '
103 'network or server operator'))
104 except httplib.HTTPException as e:
105 raise error.RichIOError(
106 _('HTTP request error (%s)') % e,
107 hint=_('this may be an intermittent failure; '
108 'if the error persists, consider contacting the '
109 'network or server operator'))
110
111 resp.__class__ = readerproxy
112
78 class httppeer(wireproto.wirepeer):
113 class httppeer(wireproto.wirepeer):
79 def __init__(self, ui, path):
114 def __init__(self, ui, path):
80 self.path = path
115 self.path = path
@@ -223,6 +258,10 class httppeer(wireproto.wirepeer):
223 self.ui.debug('http error while sending %s command\n' % cmd)
258 self.ui.debug('http error while sending %s command\n' % cmd)
224 self.ui.traceback()
259 self.ui.traceback()
225 raise IOError(None, inst)
260 raise IOError(None, inst)
261
262 # Insert error handlers for common I/O failures.
263 _wraphttpresponse(resp)
264
226 # record the url we got redirected to
265 # record the url we got redirected to
227 resp_url = resp.geturl()
266 resp_url = resp.geturl()
228 if resp_url.endswith(qs):
267 if resp_url.endswith(qs):
@@ -267,10 +267,10 Server sends an incomplete capabilities
267 $ hg --config badserver.closeaftersendbytes=180 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
267 $ hg --config badserver.closeaftersendbytes=180 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
268 $ cat hg.pid > $DAEMON_PIDS
268 $ cat hg.pid > $DAEMON_PIDS
269
269
270 TODO client spews a stack due to uncaught httplib.IncompleteRead
270 $ hg clone http://localhost:$HGPORT/ clone
271
271 abort: HTTP request error (incomplete response; expected 385 bytes got 20)
272 $ hg clone http://localhost:$HGPORT/ clone 2> /dev/null
272 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
273 [1]
273 [255]
274
274
275 $ killdaemons.py $DAEMON_PIDS
275 $ killdaemons.py $DAEMON_PIDS
276
276
@@ -461,11 +461,11 Server sends empty HTTP body for getbund
461 $ hg --config badserver.closeaftersendbytes=933 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
461 $ hg --config badserver.closeaftersendbytes=933 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
462 $ cat hg.pid > $DAEMON_PIDS
462 $ cat hg.pid > $DAEMON_PIDS
463
463
464 TODO client spews a stack due to uncaught httplib.IncompleteRead
464 $ hg clone http://localhost:$HGPORT/ clone
465
466 $ hg clone http://localhost:$HGPORT/ clone 2> /dev/null
467 requesting all changes
465 requesting all changes
468 [1]
466 abort: HTTP request error (incomplete response)
467 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
468 [255]
469
469
470 $ killdaemons.py $DAEMON_PIDS
470 $ killdaemons.py $DAEMON_PIDS
471
471
@@ -525,11 +525,11 Server sends partial compression string
525 $ hg --config badserver.closeaftersendbytes=945 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
525 $ hg --config badserver.closeaftersendbytes=945 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
526 $ cat hg.pid > $DAEMON_PIDS
526 $ cat hg.pid > $DAEMON_PIDS
527
527
528 TODO client spews a stack due to uncaught httplib.IncompleteRead
528 $ hg clone http://localhost:$HGPORT/ clone
529
530 $ hg clone http://localhost:$HGPORT/ clone 2> /dev/null
531 requesting all changes
529 requesting all changes
532 [1]
530 abort: HTTP request error (incomplete response; expected 1 bytes got 3)
531 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
532 [255]
533
533
534 $ killdaemons.py $DAEMON_PIDS
534 $ killdaemons.py $DAEMON_PIDS
535
535
@@ -593,7 +593,8 Server sends partial bundle2 header magi
593
593
594 $ hg clone http://localhost:$HGPORT/ clone
594 $ hg clone http://localhost:$HGPORT/ clone
595 requesting all changes
595 requesting all changes
596 abort: connection ended unexpectedly
596 abort: HTTP request error (incomplete response; expected 1 bytes got 3)
597 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
597 [255]
598 [255]
598
599
599 $ killdaemons.py $DAEMON_PIDS
600 $ killdaemons.py $DAEMON_PIDS
@@ -616,7 +617,8 Server sends incomplete bundle2 stream p
616
617
617 $ hg clone http://localhost:$HGPORT/ clone
618 $ hg clone http://localhost:$HGPORT/ clone
618 requesting all changes
619 requesting all changes
619 abort: connection ended unexpectedly
620 abort: HTTP request error (incomplete response; expected 1 bytes got 3)
621 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
620 [255]
622 [255]
621
623
622 $ killdaemons.py $DAEMON_PIDS
624 $ killdaemons.py $DAEMON_PIDS
@@ -640,7 +642,8 Servers stops after bundle2 stream param
640
642
641 $ hg clone http://localhost:$HGPORT/ clone
643 $ hg clone http://localhost:$HGPORT/ clone
642 requesting all changes
644 requesting all changes
643 abort: connection ended unexpectedly
645 abort: HTTP request error (incomplete response)
646 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
644 [255]
647 [255]
645
648
646 $ killdaemons.py $DAEMON_PIDS
649 $ killdaemons.py $DAEMON_PIDS
@@ -664,7 +667,8 Server stops sending after bundle2 part
664
667
665 $ hg clone http://localhost:$HGPORT/ clone
668 $ hg clone http://localhost:$HGPORT/ clone
666 requesting all changes
669 requesting all changes
667 abort: connection ended unexpectedly
670 abort: HTTP request error (incomplete response)
671 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
668 [255]
672 [255]
669
673
670 $ killdaemons.py $DAEMON_PIDS
674 $ killdaemons.py $DAEMON_PIDS
@@ -785,7 +789,8 Server stops sending after 0 length payl
785 added 1 changesets with 1 changes to 1 files
789 added 1 changesets with 1 changes to 1 files
786 transaction abort!
790 transaction abort!
787 rollback completed
791 rollback completed
788 abort: connection ended unexpectedly
792 abort: HTTP request error (incomplete response)
793 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
789 [255]
794 [255]
790
795
791 $ killdaemons.py $DAEMON_PIDS
796 $ killdaemons.py $DAEMON_PIDS
General Comments 0
You need to be logged in to leave comments. Login now