Rev 6292: (jelmer) Allow registering custom error handlers for the HPSS remote client. in file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/%2Btrunk/
Patch Queue Manager
pqm at pqm.ubuntu.com
Thu Nov 24 17:50:22 UTC 2011
At file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 6292 [merge]
revision-id: pqm at pqm.ubuntu.com-20111124175022-so5nve7kjo1p8stx
parent: pqm at pqm.ubuntu.com-20111124172541-3y61o9wf6onqh84q
parent: jelmer at samba.org-20111123133705-cz3lqog2ydtmjsel
committer: Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2011-11-24 17:50:22 +0000
message:
(jelmer) Allow registering custom error handlers for the HPSS remote client.
(Jelmer Vernooij)
modified:
bzrlib/remote.py remote.py-20060720103555-yeeg2x51vn0rbtdp-1
bzrlib/tests/test_remote.py test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
doc/en/release-notes/bzr-2.5.txt bzr2.5.txt-20110708125756-587p0hpw7oke4h05-1
=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py 2011-11-24 16:09:33 +0000
+++ b/bzrlib/remote.py 2011-11-24 17:50:22 +0000
@@ -27,6 +27,7 @@
graph,
lock,
lockdir,
+ registry,
repository as _mod_repository,
revision as _mod_revision,
static_tuple,
@@ -3457,6 +3458,10 @@
tar.extract(tarinfo, to_dir)
+error_translators = registry.Registry()
+no_context_error_translators = registry.Registry()
+
+
def _translate_error(err, **context):
"""Translate an ErrorFromSmartServer into a more useful error.
@@ -3491,67 +3496,91 @@
'Missing key %r in context %r', key_err.args[0], context)
raise err
- if err.error_verb == 'NoSuchRevision':
- raise NoSuchRevision(find('branch'), err.error_args[0])
- elif err.error_verb == 'nosuchrevision':
- raise NoSuchRevision(find('repository'), err.error_args[0])
- elif err.error_verb == 'nobranch':
- if len(err.error_args) >= 1:
- extra = err.error_args[0]
- else:
- extra = None
- raise errors.NotBranchError(path=find('bzrdir').root_transport.base,
- detail=extra)
- elif err.error_verb == 'norepository':
- raise errors.NoRepositoryPresent(find('bzrdir'))
- elif err.error_verb == 'UnlockableTransport':
- raise errors.UnlockableTransport(find('bzrdir').root_transport)
- elif err.error_verb == 'TokenMismatch':
- raise errors.TokenMismatch(find('token'), '(remote token)')
- elif err.error_verb == 'Diverged':
- raise errors.DivergedBranches(find('branch'), find('other_branch'))
- elif err.error_verb == 'NotStacked':
- raise errors.NotStacked(branch=find('branch'))
- elif err.error_verb == 'PermissionDenied':
- path = get_path()
- if len(err.error_args) >= 2:
- extra = err.error_args[1]
- else:
- extra = None
- raise errors.PermissionDenied(path, extra=extra)
- elif err.error_verb == 'ReadError':
- path = get_path()
- raise errors.ReadError(path)
- elif err.error_verb == 'NoSuchFile':
- path = get_path()
- raise errors.NoSuchFile(path)
- _translate_error_without_context(err)
-
-
-def _translate_error_without_context(err):
- """Translate any ErrorFromSmartServer values that don't require context"""
- if err.error_verb == 'IncompatibleRepositories':
- raise errors.IncompatibleRepositories(err.error_args[0],
- err.error_args[1], err.error_args[2])
- elif err.error_verb == 'LockContention':
- raise errors.LockContention('(remote lock)')
- elif err.error_verb == 'LockFailed':
- raise errors.LockFailed(err.error_args[0], err.error_args[1])
- elif err.error_verb == 'TipChangeRejected':
- raise errors.TipChangeRejected(err.error_args[0].decode('utf8'))
- elif err.error_verb == 'UnstackableBranchFormat':
- raise errors.UnstackableBranchFormat(*err.error_args)
- elif err.error_verb == 'UnstackableRepositoryFormat':
- raise errors.UnstackableRepositoryFormat(*err.error_args)
- elif err.error_verb == 'FileExists':
- raise errors.FileExists(err.error_args[0])
- elif err.error_verb == 'DirectoryNotEmpty':
- raise errors.DirectoryNotEmpty(err.error_args[0])
- elif err.error_verb == 'ShortReadvError':
- args = err.error_args
- raise errors.ShortReadvError(
- args[0], int(args[1]), int(args[2]), int(args[3]))
- elif err.error_verb in ('UnicodeEncodeError', 'UnicodeDecodeError'):
+ try:
+ translator = error_translators.get(err.error_verb)
+ except KeyError:
+ pass
+ else:
+ raise translator(err, find, get_path)
+ try:
+ translator = no_context_error_translators.get(err.error_verb)
+ except KeyError:
+ raise errors.UnknownErrorFromSmartServer(err)
+ else:
+ raise translator(err)
+
+
+error_translators.register('NoSuchRevision',
+ lambda err, find, get_path: NoSuchRevision(
+ find('branch'), err.error_args[0]))
+error_translators.register('nosuchrevision',
+ lambda err, find, get_path: NoSuchRevision(
+ find('repository'), err.error_args[0]))
+
+def _translate_nobranch_error(err, find, get_path):
+ if len(err.error_args) >= 1:
+ extra = err.error_args[0]
+ else:
+ extra = None
+ return errors.NotBranchError(path=find('bzrdir').root_transport.base,
+ detail=extra)
+
+error_translators.register('nobranch', _translate_nobranch_error)
+error_translators.register('norepository',
+ lambda err, find, get_path: errors.NoRepositoryPresent(
+ find('bzrdir')))
+error_translators.register('UnlockableTransport',
+ lambda err, find, get_path: errors.UnlockableTransport(
+ find('bzrdir').root_transport))
+error_translators.register('TokenMismatch',
+ lambda err, find, get_path: errors.TokenMismatch(
+ find('token'), '(remote token)'))
+error_translators.register('Diverged',
+ lambda err, find, get_path: errors.DivergedBranches(
+ find('branch'), find('other_branch')))
+error_translators.register('NotStacked',
+ lambda err, find, get_path: errors.NotStacked(branch=find('branch')))
+
+def _translate_PermissionDenied(err, find, get_path):
+ path = get_path()
+ if len(err.error_args) >= 2:
+ extra = err.error_args[1]
+ else:
+ extra = None
+ return errors.PermissionDenied(path, extra=extra)
+
+error_translators.register('PermissionDenied', _translate_PermissionDenied)
+error_translators.register('ReadError',
+ lambda err, find, get_path: errors.ReadError(get_path()))
+error_translators.register('NoSuchFile',
+ lambda err, find, get_path: errors.NoSuchFile(get_path()))
+no_context_error_translators.register('IncompatibleRepositories',
+ lambda err: errors.IncompatibleRepositories(
+ err.error_args[0], err.error_args[1], err.error_args[2]))
+no_context_error_translators.register('LockContention',
+ lambda err: errors.LockContention('(remote lock)'))
+no_context_error_translators.register('LockFailed',
+ lambda err: errors.LockFailed(err.error_args[0], err.error_args[1]))
+no_context_error_translators.register('TipChangeRejected',
+ lambda err: errors.TipChangeRejected(err.error_args[0].decode('utf8')))
+no_context_error_translators.register('UnstackableBranchFormat',
+ lambda err: errors.UnstackableBranchFormat(*err.error_args))
+no_context_error_translators.register('UnstackableRepositoryFormat',
+ lambda err: errors.UnstackableRepositoryFormat(*err.error_args))
+no_context_error_translators.register('FileExists',
+ lambda err: errors.FileExists(err.error_args[0]))
+no_context_error_translators.register('DirectoryNotEmpty',
+ lambda err: errors.DirectoryNotEmpty(err.error_args[0]))
+
+def _translate_short_readv_error(err):
+ args = err.error_args
+ return errors.ShortReadvError(args[0], int(args[1]), int(args[2]),
+ int(args[3]))
+
+no_context_error_translators.register('ShortReadvError',
+ _translate_short_readv_error)
+
+def _translate_unicode_error(err):
encoding = str(err.error_args[0]) # encoding must always be a string
val = err.error_args[1]
start = int(err.error_args[2])
@@ -3565,9 +3594,13 @@
raise UnicodeDecodeError(encoding, val, start, end, reason)
elif err.error_verb == 'UnicodeEncodeError':
raise UnicodeEncodeError(encoding, val, start, end, reason)
- elif err.error_verb == 'ReadOnlyError':
- raise errors.TransportNotPossible('readonly transport')
- elif err.error_verb == 'MemoryError':
- raise errors.BzrError("remote server out of memory\n"
- "Retry non-remotely, or contact the server admin for details.")
- raise errors.UnknownErrorFromSmartServer(err)
+
+no_context_error_translators.register('UnicodeEncodeError',
+ _translate_unicode_error)
+no_context_error_translators.register('UnicodeDecodeError',
+ _translate_unicode_error)
+no_context_error_translators.register('ReadOnlyError',
+ lambda err: errors.TransportNotPossible('readonly transport'))
+no_context_error_translators.register('MemoryError',
+ lambda err: errors.BzrError("remote server out of memory\n"
+ "Retry non-remotely, or contact the server admin for details."))
=== modified file 'bzrlib/tests/test_remote.py'
--- a/bzrlib/tests/test_remote.py 2011-11-22 13:27:04 +0000
+++ b/bzrlib/tests/test_remote.py 2011-11-23 13:37:05 +0000
@@ -3670,3 +3670,52 @@
# interpretation
self.make_master_and_checkout('mas~ter', 'checkout')
self.assertUpdateSucceeds(self.bound_location.replace('%2E', '~', 1))
+
+
+class TestWithCustomErrorHandler(RemoteBranchTestCase):
+
+ def test_no_context(self):
+ class OutOfCoffee(errors.BzrError):
+ """A dummy exception for testing."""
+
+ def __init__(self, urgency):
+ self.urgency = urgency
+ remote.no_context_error_translators.register("OutOfCoffee",
+ lambda err: OutOfCoffee(err.error_args[0]))
+ transport = MemoryTransport()
+ client = FakeClient(transport.base)
+ client.add_expected_call(
+ 'Branch.get_stacked_on_url', ('quack/',),
+ 'error', ('NotStacked',))
+ client.add_expected_call(
+ 'Branch.last_revision_info',
+ ('quack/',),
+ 'error', ('OutOfCoffee', 'low'))
+ transport.mkdir('quack')
+ transport = transport.clone('quack')
+ branch = self.make_remote_branch(transport, client)
+ self.assertRaises(OutOfCoffee, branch.last_revision_info)
+ self.assertFinished(client)
+
+ def test_with_context(self):
+ class OutOfTea(errors.BzrError):
+ def __init__(self, branch, urgency):
+ self.branch = branch
+ self.urgency = urgency
+ remote.error_translators.register("OutOfTea",
+ lambda err, find, path: OutOfTea(err.error_args[0],
+ find("branch")))
+ transport = MemoryTransport()
+ client = FakeClient(transport.base)
+ client.add_expected_call(
+ 'Branch.get_stacked_on_url', ('quack/',),
+ 'error', ('NotStacked',))
+ client.add_expected_call(
+ 'Branch.last_revision_info',
+ ('quack/',),
+ 'error', ('OutOfTea', 'low'))
+ transport.mkdir('quack')
+ transport = transport.clone('quack')
+ branch = self.make_remote_branch(transport, client)
+ self.assertRaises(OutOfTea, branch.last_revision_info)
+ self.assertFinished(client)
=== modified file 'doc/en/release-notes/bzr-2.5.txt'
--- a/doc/en/release-notes/bzr-2.5.txt 2011-11-24 14:30:59 +0000
+++ b/doc/en/release-notes/bzr-2.5.txt 2011-11-24 17:50:22 +0000
@@ -101,6 +101,10 @@
``BzrDir.has_workingtree`` and ``Branch.put_config_file``.
(Jelmer Vernooij)
+* Custom HPSS error handlers can now be installed in the smart server client
+ using the ``error_translators`` and ``no_context_error_translators``
+ registries. (Jelmer Vernooij)
+
Testing
*******
More information about the bazaar-commits
mailing list