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.
This commit is contained in:
Pierre-Yves David 2015-05-27 23:48:54 -07:00
parent 1ca77932d5
commit 4386f8310a
2 changed files with 20 additions and 2 deletions

View File

@ -1330,8 +1330,11 @@ def handlepushkey(op, inpart):
rpart.addparam('in-reply-to', str(inpart.id), mandatory=False) rpart.addparam('in-reply-to', str(inpart.id), mandatory=False)
rpart.addparam('return', '%i' % ret, mandatory=False) rpart.addparam('return', '%i' % ret, mandatory=False)
if inpart.mandatory and not ret: if inpart.mandatory and not ret:
raise util.Abort(_('failed to update value for "%s/%s"') kwargs = {}
% (namespace, key)) 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')) @parthandler('reply:pushkey', ('return', 'in-reply-to'))
def handlepushkeyreply(op, inpart): def handlepushkeyreply(op, inpart):

View File

@ -151,6 +151,21 @@ class ReadOnlyPartError(RuntimeError):
"""error raised when code tries to alter a part being generated""" """error raised when code tries to alter a part being generated"""
pass 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): class CensoredNodeError(RevlogError):
"""error raised when content verification fails on a censored node """error raised when content verification fails on a censored node