# HG changeset patch # User Pierre-Yves David <pierre-yves.david@ens-lyon.org> # Date 1486747258 -3600 # Fri Feb 10 18:20:58 2017 +0100 # Branch stable # Node ID f3807a135e43b0499db12dc79697e0b9589dd095 # Parent d70971a3ae80fbebdca7a0e3adb72370f08f60e1 wireproto: properly report server Abort during 'getbundle' Previously Abort raised during 'getbundle' call poorly reported (HTTP-500 for http, some scary messages for ssh). Abort error have been properly reported for "push" for a long time, there is not reason to be different for 'getbundle'. We properly catch such error and report them back the best way available. For bundle, we issue a valid bundle2 reply (as expected by the client) with an 'error:abort' part. With bundle1 we do as best as we can depending of http or ssh. diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -839,7 +839,24 @@ raise error.Abort(bundle2requiredmain, hint=bundle2requiredhint) - chunks = exchange.getbundlechunks(repo, 'serve', **opts) + #chunks = exchange.getbundlechunks(repo, 'serve', **opts) + try: + chunks = exchange.getbundlechunks(repo, 'serve', **opts) + except error.Abort as exc: + # cleanly forward Abort error to the client + if not exchange.bundle2requested(opts.get('bundlecaps')): + if proto.name == 'http': + return ooberror(str(exc) + '\n') + raise # cannot do better for bundle1 + ssh + # bundle2 request expect a bundle2 reply + bundler = bundle2.bundle20(repo.ui) + manargs = [('message', str(exc))] + advargs = [] + if exc.hint is not None: + advargs.append(('hint', exc.hint)) + bundler.addpart(bundle2.bundlepart('error:abort', + manargs, advargs)) + return streamres(gen=bundler.getchunks(), v1compressible=True) return streamres(gen=chunks, v1compressible=True) @wireprotocommand('heads') diff --git a/tests/crashgetbundler.py b/tests/crashgetbundler.py new file mode 100644 --- /dev/null +++ b/tests/crashgetbundler.py @@ -0,0 +1,14 @@ +from __future__ import absolute_import + +from mercurial.i18n import _ +from mercurial import ( + changegroup, + error, + extensions + ) + +def abort(orig, *args, **kwargs): + raise error.Abort(_('this is an exercise')) + +def uisetup(ui): + extensions.wrapfunction(changegroup, 'getbundler', abort) diff --git a/tests/test-http-bundle1.t b/tests/test-http-bundle1.t --- a/tests/test-http-bundle1.t +++ b/tests/test-http-bundle1.t @@ -333,3 +333,15 @@ check error log $ cat error.log + +Check error reporting while pulling/cloning + + $ $RUNTESTDIR/killdaemons.py + $ hg -R test serve -p $HGPORT -d --pid-file=hg3.pid -E error.log --config extensions.crash=${TESTDIR}/crashgetbundler.py + $ cat hg3.pid >> $DAEMON_PIDS + $ hg clone http://localhost:$HGPORT/ abort-clone + requesting all changes + abort: remote error: + this is an exercise + [255] + $ cat error.log diff --git a/tests/test-http.t b/tests/test-http.t --- a/tests/test-http.t +++ b/tests/test-http.t @@ -321,3 +321,15 @@ check error log $ cat error.log + +check abort error reporting while pulling/cloning + + $ $RUNTESTDIR/killdaemons.py + $ hg -R test serve -p $HGPORT -d --pid-file=hg3.pid -E error.log --config extensions.crash=${TESTDIR}/crashgetbundler.py + $ cat hg3.pid >> $DAEMON_PIDS + $ hg clone http://localhost:$HGPORT/ abort-clone + requesting all changes + remote: abort: this is an exercise + abort: pull failed on remote + [255] + $ cat error.log diff --git a/tests/test-ssh-bundle1.t b/tests/test-ssh-bundle1.t --- a/tests/test-ssh-bundle1.t +++ b/tests/test-ssh-bundle1.t @@ -543,3 +543,20 @@ remote: abort: pretxnchangegroup.fail hook failed [1] +abort during pull is properly reported as such + + $ echo morefoo >> ../remote/foo + $ hg -R ../remote commit --message "more foo to be pulled" + $ cat >> ../remote/.hg/hgrc << EOF + > [extensions] + > crash = ${TESTDIR}/crashgetbundler.py + > EOF + $ hg --config ui.ssh="python $TESTDIR/dummyssh" pull + pulling from ssh://user@dummy/remote + searching for changes + adding changesets + remote: abort: this is an exercise + transaction abort! + rollback completed + abort: stream ended unexpectedly (got 0 bytes, expected 4) + [255] diff --git a/tests/test-ssh.t b/tests/test-ssh.t --- a/tests/test-ssh.t +++ b/tests/test-ssh.t @@ -548,3 +548,17 @@ abort: push failed on remote [255] +abort during pull is properly reported as such + + $ echo morefoo >> ../remote/foo + $ hg -R ../remote commit --message "more foo to be pulled" + $ cat >> ../remote/.hg/hgrc << EOF + > [extensions] + > crash = ${TESTDIR}/crashgetbundler.py + > EOF + $ hg --config ui.ssh="python $TESTDIR/dummyssh" pull + pulling from ssh://user@dummy/remote + searching for changes + remote: abort: this is an exercise + abort: pull failed on remote + [255]