# HG changeset patch # User Pierre-Yves David # Date 1432795734 25200 # Node ID a5192774e9256b695ae4bc846c1e2c3947a62840 # Parent fb04372d7b38c0b371a650ef10f9d02d868c1367 bundle2: introduce a PushkeyFail error to abort unbundle on pushkey error The pushkey code is generic and the server side has little context on what the client is trying to achieve. Generating interesting error messages server side would be challenging. Instead we introduce a dedicated exception that carries more data. In particular, it carries the id of the part which failed that will allow clients to display custom error messages depending on the part intent. The processing and transfer-over-the-wire of this exception is to be implemented in coming changesets. diff -r fb04372d7b38 -r a5192774e925 mercurial/bundle2.py --- a/mercurial/bundle2.py Fri Jun 05 13:31:18 2015 -0700 +++ b/mercurial/bundle2.py Wed May 27 23:48:54 2015 -0700 @@ -1330,8 +1330,11 @@ rpart.addparam('in-reply-to', str(inpart.id), mandatory=False) rpart.addparam('return', '%i' % ret, mandatory=False) if inpart.mandatory and not ret: - raise util.Abort(_('failed to update value for "%s/%s"') - % (namespace, key)) + kwargs = {} + for key in ('namespace', 'key', 'new', 'old', 'ret'): + if key in inpart.params: + kwargs[key] = inpart.params[key] + raise error.PushkeyFailed(partid=str(inpart.id), **kwargs) @parthandler('reply:pushkey', ('return', 'in-reply-to')) def handlepushkeyreply(op, inpart): diff -r fb04372d7b38 -r a5192774e925 mercurial/error.py --- a/mercurial/error.py Fri Jun 05 13:31:18 2015 -0700 +++ b/mercurial/error.py Wed May 27 23:48:54 2015 -0700 @@ -151,6 +151,21 @@ """error raised when code tries to alter a part being generated""" pass +class PushkeyFailed(Abort): + """error raised when a pushkey part failed to update a value""" + + def __init__(self, partid, namespace=None, key=None, new=None, old=None, + ret=None): + self.partid = partid + self.namespace = namespace + self.key = key + self.new = new + self.old = old + self.ret = ret + # no i18n expected to be processed into a better message + Abort.__init__(self, 'failed to update value for "%s/%s"' + % (namespace, key)) + class CensoredNodeError(RevlogError): """error raised when content verification fails on a censored node