diff mercurial/exchange.py @ 25485:8182163ae983

push: catch and process PushkeyFailed error We add a way to register "pushkey failure callback" that will be used if the push is aborted by a pushkey failure. A part generator adding mandatory pushkey parts should register a failure callback for all of them. The callback will be in charge of generating a meaningful abort if this part fails. If no callback is registered, the error is propagated. Catch PushkeyFailed error in exchange.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Fri, 05 Jun 2015 16:30:11 -0700
parents d410336fdb3c
children a99fee62611d
line wrap: on
line diff
--- a/mercurial/exchange.py	Wed May 27 23:48:54 2015 -0700
+++ b/mercurial/exchange.py	Fri Jun 05 16:30:11 2015 -0700
@@ -117,6 +117,9 @@
         self.outbookmarks = []
         # transaction manager
         self.trmanager = None
+        # map { pushkey partid -> callback handling failure}
+        # used to handle exception from mandatory pushkey part failure
+        self.pkfailcb = {}
 
     @util.propertycache
     def futureheads(self):
@@ -623,16 +626,22 @@
         return
     stream = util.chunkbuffer(bundler.getchunks())
     try:
-        reply = pushop.remote.unbundle(stream, ['force'], 'push')
-    except error.BundleValueError, exc:
-        raise util.Abort('missing support for %s' % exc)
-    try:
-        trgetter = None
-        if pushback:
-            trgetter = pushop.trmanager.transaction
-        op = bundle2.processbundle(pushop.repo, reply, trgetter)
-    except error.BundleValueError, exc:
-        raise util.Abort('missing support for %s' % exc)
+        try:
+            reply = pushop.remote.unbundle(stream, ['force'], 'push')
+        except error.BundleValueError, exc:
+            raise util.Abort('missing support for %s' % exc)
+        try:
+            trgetter = None
+            if pushback:
+                trgetter = pushop.trmanager.transaction
+            op = bundle2.processbundle(pushop.repo, reply, trgetter)
+        except error.BundleValueError, exc:
+            raise util.Abort('missing support for %s' % exc)
+    except error.PushkeyFailed, exc:
+        partid = int(exc.partid)
+        if partid not in pushop.pkfailcb:
+            raise
+        pushop.pkfailcb[partid](pushop, exc)
     for rephand in replyhandlers:
         rephand(op)