changeset 21183:4345274adc4b stable

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.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Mon, 21 Apr 2014 16:02:03 -0700
parents 08c84fd99aac
children 28d76afa1568
files mercurial/bundle2.py mercurial/wireproto.py tests/test-bundle2.t
diffstat 3 files changed, 38 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/bundle2.py	Tue Apr 22 11:41:34 2014 -0700
+++ b/mercurial/bundle2.py	Mon Apr 21 16:02:03 2014 -0700
@@ -753,3 +753,9 @@
     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'])
--- a/mercurial/wireproto.py	Tue Apr 22 11:41:34 2014 -0700
+++ b/mercurial/wireproto.py	Mon Apr 21 16:02:03 2014 -0700
@@ -803,6 +803,12 @@
         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.
--- a/tests/test-bundle2.t	Tue Apr 22 11:41:34 2014 -0700
+++ b/tests/test-bundle2.t	Mon Apr 21 16:02:03 2014 -0700
@@ -908,6 +908,8 @@
   >     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
@@ -969,3 +971,27 @@
   [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]