wireprotov1peer: don't raise internal errors in some cases
Specifically, when the peer is closed in the middle of a batch of rpcs.
Differential Revision: https://phab.mercurial-scm.org/D10074
--- a/mercurial/scmutil.py Thu Feb 25 10:00:08 2021 -0500
+++ b/mercurial/scmutil.py Thu Feb 25 10:08:33 2021 -0500
@@ -201,7 +201,9 @@
msg = inst.args[1]
if isinstance(msg, type(u'')):
msg = pycompat.sysbytes(msg)
- if not isinstance(msg, bytes):
+ if msg is None:
+ ui.error(b"\n")
+ elif not isinstance(msg, bytes):
ui.error(b" %r\n" % (msg,))
elif not msg:
ui.error(_(b" empty string\n"))
--- a/mercurial/wireprotov1peer.py Thu Feb 25 10:00:08 2021 -0500
+++ b/mercurial/wireprotov1peer.py Thu Feb 25 10:08:33 2021 -0500
@@ -310,7 +310,7 @@
if not f.done():
f.set_exception(
error.ResponseError(
- _(b'unfulfilled batch command response')
+ _(b'unfulfilled batch command response'), None
)
)
@@ -322,16 +322,27 @@
for command, f, batchable, fremote in states:
# Grab raw result off the wire and teach the internal future
# about it.
- remoteresult = next(wireresults)
- fremote.set(remoteresult)
+ try:
+ remoteresult = next(wireresults)
+ except StopIteration:
+ # This can happen in particular because next(batchable)
+ # in the previous iteration can call peer._abort, which
+ # may close the peer.
+ f.set_exception(
+ error.ResponseError(
+ _(b'unfulfilled batch command response'), None
+ )
+ )
+ else:
+ fremote.set(remoteresult)
- # And ask the coroutine to decode that value.
- try:
- result = next(batchable)
- except Exception:
- pycompat.future_set_exception_info(f, sys.exc_info()[1:])
- else:
- f.set_result(result)
+ # And ask the coroutine to decode that value.
+ try:
+ result = next(batchable)
+ except Exception:
+ pycompat.future_set_exception_info(f, sys.exc_info()[1:])
+ else:
+ f.set_result(result)
@interfaceutil.implementer(
--- a/tests/test-ssh-batch.t Thu Feb 25 10:00:08 2021 -0500
+++ b/tests/test-ssh-batch.t Thu Feb 25 10:08:33 2021 -0500
@@ -9,5 +9,7 @@
fails (thus causing the sshpeer to be stopped), the errors from the
further lookups don't result in tracebacks.
- $ hg pull -r b0 -r nosuchbookmark $(for i in $($TESTDIR/seq.py 1 20); do echo -r b$i; done) -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/$(pwd)/../a |& tail -n 1
- StopIteration
+ $ hg pull -r b0 -r nosuchbookmark $(for i in $($TESTDIR/seq.py 1 20); do echo -r b$i; done) -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/$(pwd)/../a
+ pulling from ssh://user@dummy/$TESTTMP/b/../a
+ abort: unknown revision 'nosuchbookmark'
+ [255]