From patchwork Tue Apr 22 20:10:52 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [08, of, 12, stable] bundle2: gracefully handle UnknownPartError during unbundle From: Pierre-Yves David X-Patchwork-Id: 4427 Message-Id: To: mercurial-devel@selenic.com Cc: pierre-yves.david@ens-lyon.org Date: Tue, 22 Apr 2014 13:10:52 -0700 # HG changeset patch # User Pierre-Yves David # Date 1398121323 25200 # Mon Apr 21 16:02:03 2014 -0700 # Branch stable # Node ID db91dd50bd02279afe60da8dd3a33b299ff517da # Parent 6ab6a29964dbf3113ba85f1d8755610eb03e283f bundle2: gracefully handle UnknownPartError during unbundle Same as for Abort error, we catch the error, encode it into a bundle2 reply (expected by the client) and stream this reply. The client processing of the error will raise the exception again. diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py --- a/mercurial/bundle2.py +++ b/mercurial/bundle2.py @@ -751,5 +751,11 @@ def handlereplycaps(op, inpart): def handlereplycaps(op, inpart): """Used to transmit abort error over the wire""" manargs = dict(inpart.mandatoryparams) advargs = dict(inpart.advisoryparams) raise util.Abort(manargs['message'], hint=advargs.get('hint')) + +@parthandler('b2x:error:unknownpart') +def handlereplycaps(op, inpart): + """Used to transmit unknown part error over the wire""" + manargs = dict(inpart.mandatoryparams) + raise UnknownPartError(manargs['parttype']) diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -801,10 +801,16 @@ def unbundle(repo, proto, heads): return pushres(r) finally: fp.close() os.unlink(tempname) + except bundle2.UnknownPartError, exc: + bundler = bundle2.bundle20(repo.ui) + part = bundle2.bundlepart('B2X:ERROR:UNKNOWNPART', + [('parttype', str(exc))]) + bundler.addpart(part) + return streamres(bundler.getchunks()) except util.Abort, inst: # The old code we moved used sys.stderr directly. # We did not change it to minimise code change. # This need to be moved to something proper. # Feel free to do it. diff --git a/tests/test-bundle2.t b/tests/test-bundle2.t --- a/tests/test-bundle2.t +++ b/tests/test-bundle2.t @@ -906,10 +906,12 @@ Setting up > extradata = orig(pushop, bundler) > reason = pushop.ui.config('failpush', 'reason', None) > part = None > if reason == 'abort': > part = bundle2.bundlepart('test:abort') + > if reason == 'unknown': + > part = bundle2.bundlepart('TEST:UNKNOWN') > if part is not None: > bundler.addpart(part) > return extradata > > @bundle2.parthandler("test:abort") @@ -967,5 +969,29 @@ Doing the actual push: Abort error abort: Abandon ship! (don't panic) [255] +Doing the actual push: unknown mandatory parts + + $ cat << EOF >> $HGRCPATH + > [failpush] + > reason = unknown + > EOF + + $ hg -R main push other -r e7ec4e813ba6 + pushing to other + searching for changes + abort: missing support for 'test:unknown' + [255] + + $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6 + pushing to ssh://user@dummy/other + searching for changes + abort: missing support for "'test:unknown'" + [255] + + $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6 + pushing to http://localhost:$HGPORT2/ + searching for changes + abort: missing support for "'test:unknown'" + [255]