diff options
| author | Johannes Erdfelt <johannes.erdfelt@rackspace.com> | 2011-10-31 15:11:36 +0000 |
|---|---|---|
| committer | Johannes Erdfelt <johannes.erdfelt@rackspace.com> | 2011-10-31 16:42:47 +0000 |
| commit | e2403739d5e866e011ecc45a4d5b20d5e0192997 (patch) | |
| tree | f3593bac5cc6b934f4e122d8a55d02f8599e8bce /nova | |
| parent | 5b8133a83939fd552b569c4b034cef43907ea1ce (diff) | |
Log original dropped exception when a new exception occurs
If a exception is caught while processing a previous exception, make sure
to log it so it doesn't silently get discarded
Change-Id: Ic887db9c2592229970737daf5dd9732b2258877b
Diffstat (limited to 'nova')
| -rw-r--r-- | nova/compute/manager.py | 2 | ||||
| -rw-r--r-- | nova/exception.py | 2 | ||||
| -rw-r--r-- | nova/utils.py | 22 | ||||
| -rw-r--r-- | nova/virt/xenapi/vm_utils.py | 2 |
4 files changed, 18 insertions, 10 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py index f133ee133..054e682a5 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -470,7 +470,7 @@ class ComputeManager(manager.SchedulerDependentManager): # be fixed once we have no-db-messaging pass except: - with utils.original_exception_raised(): + with utils.save_and_reraise_exception(): _deallocate_network() def _get_instance_volume_bdms(self, context, instance_id): diff --git a/nova/exception.py b/nova/exception.py index 998fece1e..872f532f9 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -107,6 +107,8 @@ def wrap_exception(notifier=None, publisher_id=None, event_type=None, # TODO(sandy): Find a way to import nova.notifier.api so we don't have # to pass it in as a parameter. Otherwise we get a cyclic import of # nova.notifier.api -> nova.utils -> nova.exception :( + # TODO(johannes): Also, it would be nice to use + # utils.save_and_reraise_exception() without an import loop def inner(f): def wrapped(*args, **kw): try: diff --git a/nova/utils.py b/nova/utils.py index ad585ba1c..baa47102c 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -979,21 +979,27 @@ def generate_glance_url(): @contextlib.contextmanager -def original_exception_raised(): - """Run some code, then re-raise the original exception. +def save_and_reraise_exception(): + """Save current exception, run some code and then re-raise. - This is needed because when Eventlet switches greenthreads, it clears the - exception context. This means if exception handler code blocks, we'll lose - the helpful exception traceback information. + In some cases the exception context can be cleared, resulting in None + being attempted to be reraised after an exception handler is run. This + can happen when eventlet switches greenthreads or when running an + exception handler, code raises and catches and exception. In both + cases the exception context will be cleared. To work around this, we save the exception state, run handler code, and - then re-raise the original exception. + then re-raise the original exception. If another exception occurs, the + saved exception is logged and the new exception is reraised. """ type_, value, traceback = sys.exc_info() try: yield - finally: - raise type_, value, traceback + except: + LOG.exception(_('Original exception being dropped'), + exc_info=(type_, value, traceback)) + raise + raise type_, value, traceback def make_dev_path(dev, partition=None, base='/dev'): diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 7142d0457..5b08a3c69 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -523,7 +523,7 @@ w cls.create_vbd(session, vm_ref, vdi_ref, userdevice, bootable=False) except: - with utils.original_exception_raised(): + with utils.save_and_reraise_exception(): cls.destroy_vdi(session, vdi_ref) @classmethod |
