diff options
author | Andrew Melton <andrew.melton@rackspace.com> | 2014-06-17 11:31:14 -0400 |
---|---|---|
committer | Andrew Melton <andrew.melton@rackspace.com> | 2014-06-17 15:37:36 -0400 |
commit | cf6d43d774c265abd93022f273d55e24f4c3930a (patch) | |
tree | 1467b60b193b9c41ee49f8960e5de9ce38480709 /nova/hooks.py | |
parent | 25ea5f480d22e38d0d7f82f80fd651713d4b9211 (diff) | |
download | nova-cf6d43d774c265abd93022f273d55e24f4c3930a.tar.gz |
Enhance and test exception safety in hooks
This patch adds exception handling when calling pre and
post functions of hooks. Exceptions will be caught and
logged, but the hook chain and function call will be
allowed to proceed.
Partially implements: bp instance-network-info-hook
Change-Id: I45e76cd156c244ff57f77db103a9a579f14ad4f1
Diffstat (limited to 'nova/hooks.py')
-rw-r--r-- | nova/hooks.py | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/nova/hooks.py b/nova/hooks.py index adca138c21..d56455e2a1 100644 --- a/nova/hooks.py +++ b/nova/hooks.py @@ -46,6 +46,7 @@ import functools import stevedore +from nova.openstack.common.gettextutils import _LE from nova.openstack.common import log as logging LOG = logging.getLogger(__name__) @@ -54,6 +55,14 @@ NS = 'nova.hooks' _HOOKS = {} # hook name => hook manager +class FatalHookException(Exception): + """Exception which should be raised by hooks to indicate that normal + execution of the hooked function should be terminated. Raised exception + will be logged and reraised. + """ + pass + + class HookManager(stevedore.hook.HookManager): def __init__(self, name): # invoke_on_load creates an instance of the Hook class @@ -66,10 +75,19 @@ class HookManager(stevedore.hook.HookManager): if pre: LOG.debug("Running %(name)s pre-hook: %(obj)s", {'name': name, 'obj': obj}) - if f: - pre(f, *args, **kwargs) - else: - pre(*args, **kwargs) + try: + if f: + pre(f, *args, **kwargs) + else: + pre(*args, **kwargs) + except FatalHookException: + msg = _LE("Fatal Exception running %(name)s " + "pre-hook: %(obj)s") + LOG.exception(msg, {'name': name, 'obj': obj}) + raise + except Exception: + msg = _LE("Exception running %(name)s pre-hook: %(obj)s") + LOG.exception(msg, {'name': name, 'obj': obj}) def run_post(self, name, rv, args, kwargs, f=None): for e in reversed(self.extensions): @@ -78,10 +96,19 @@ class HookManager(stevedore.hook.HookManager): if post: LOG.debug("Running %(name)s post-hook: %(obj)s", {'name': name, 'obj': obj}) - if f: - post(f, rv, *args, **kwargs) - else: - post(rv, *args, **kwargs) + try: + if f: + post(f, rv, *args, **kwargs) + else: + post(rv, *args, **kwargs) + except FatalHookException: + msg = _LE("Fatal Exception running %(name)s " + "post-hook: %(obj)s") + LOG.exception(msg, {'name': name, 'obj': obj}) + raise + except Exception: + msg = _LE("Exception running %(name)s post-hook: %(obj)s") + LOG.exception(msg, {'name': name, 'obj': obj}) def add_hook(name, pass_function=False): |