Adds ability to propogate exceptions within map

Adds init variable for extension managers to specify whether
or not exceptions are propated up by map or are logged and supressed
This commit is contained in:
Chris Yeoh 2013-06-20 13:32:52 +09:30
parent 1decfbe730
commit 9f2adb4d59
5 changed files with 34 additions and 9 deletions

View File

@ -99,13 +99,15 @@ class NameDispatchExtensionManager(DispatchExtensionManager):
"""
def __init__(self, namespace, check_func, invoke_on_load=False,
invoke_args=(), invoke_kwds={}):
invoke_args=(), invoke_kwds={},
propagate_map_exceptions=False):
super(NameDispatchExtensionManager, self).__init__(
namespace=namespace,
check_func=check_func,
invoke_on_load=invoke_on_load,
invoke_args=invoke_args,
invoke_kwds=invoke_kwds,
propagate_map_exceptions=propagate_map_exceptions,
)
self.by_name = dict((e.name, e) for e in self.extensions)

View File

@ -32,13 +32,15 @@ class EnabledExtensionManager(ExtensionManager):
"""
def __init__(self, namespace, check_func, invoke_on_load=False,
invoke_args=(), invoke_kwds={}):
invoke_args=(), invoke_kwds={},
propagate_map_exceptions=False):
self.check_func = check_func
super(EnabledExtensionManager, self).__init__(
namespace,
invoke_on_load=invoke_on_load,
invoke_args=invoke_args,
invoke_kwds=invoke_kwds,
propagate_map_exceptions=propagate_map_exceptions,
)
def _load_one_plugin(self, ep, invoke_on_load, invoke_args, invoke_kwds):

View File

@ -57,8 +57,10 @@ class ExtensionManager(object):
def __init__(self, namespace,
invoke_on_load=False,
invoke_args=(),
invoke_kwds={}):
invoke_kwds={},
propagate_map_exceptions=False):
self.namespace = namespace
self.propagate_map_exceptions = propagate_map_exceptions
self.extensions = self._load_plugins(invoke_on_load,
invoke_args,
invoke_kwds)
@ -136,11 +138,11 @@ class ExtensionManager(object):
try:
response_callback(func(e, *args, **kwds))
except Exception as err:
# FIXME: Provide an argument to control
# whether to ignore exceptions in each
# plugin or stop processing.
LOG.error('error calling %r: %s', e.name, err)
LOG.exception(err)
if self.propagate_map_exceptions:
raise
else:
LOG.error('error calling %r: %s', e.name, err)
LOG.exception(err)
def __iter__(self):
"""Produce iterator for the manager.

View File

@ -29,13 +29,14 @@ class NamedExtensionManager(ExtensionManager):
def __init__(self, namespace, names,
invoke_on_load=False, invoke_args=(), invoke_kwds={},
name_order=False):
name_order=False, propagate_map_exceptions=False):
self._names = names
super(NamedExtensionManager, self).__init__(
namespace,
invoke_on_load=invoke_on_load,
invoke_args=invoke_args,
invoke_kwds=invoke_kwds,
propagate_map_exceptions=propagate_map_exceptions,
)
if name_order:

View File

@ -126,6 +126,24 @@ def test_map_eats_errors():
assert results == []
def test_map_propagate_exceptions():
def mapped(ext, *args, **kwds):
raise RuntimeError('hard coded error')
em = extension.ExtensionManager('stevedore.test.extension',
invoke_on_load=True,
propagate_map_exceptions=True
)
try:
em.map(mapped, 1, 2, a='A', b='B')
assert False
except:
pass
def test_map_errors_when_no_plugins():
def mapped(ext, *args, **kwds):