From 9f2adb4d593f58c92e73e33c0305a679eaf6b819 Mon Sep 17 00:00:00 2001 From: Chris Yeoh Date: Thu, 20 Jun 2013 13:32:52 +0930 Subject: [PATCH] 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 --- stevedore/dispatch.py | 4 +++- stevedore/enabled.py | 4 +++- stevedore/extension.py | 14 ++++++++------ stevedore/named.py | 3 ++- stevedore/tests/test_extension.py | 18 ++++++++++++++++++ 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/stevedore/dispatch.py b/stevedore/dispatch.py index 9f7a4c8..f96e731 100644 --- a/stevedore/dispatch.py +++ b/stevedore/dispatch.py @@ -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) diff --git a/stevedore/enabled.py b/stevedore/enabled.py index 6157554..0c96a1b 100644 --- a/stevedore/enabled.py +++ b/stevedore/enabled.py @@ -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): diff --git a/stevedore/extension.py b/stevedore/extension.py index 076b49d..063cf1a 100644 --- a/stevedore/extension.py +++ b/stevedore/extension.py @@ -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. diff --git a/stevedore/named.py b/stevedore/named.py index 2a3f054..63ee386 100644 --- a/stevedore/named.py +++ b/stevedore/named.py @@ -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: diff --git a/stevedore/tests/test_extension.py b/stevedore/tests/test_extension.py index bc76bbd..fb9fdd8 100644 --- a/stevedore/tests/test_extension.py +++ b/stevedore/tests/test_extension.py @@ -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):