summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorJohannes Erdfelt <johannes.erdfelt@rackspace.com>2011-10-31 15:11:36 +0000
committerJohannes Erdfelt <johannes.erdfelt@rackspace.com>2011-10-31 16:42:47 +0000
commite2403739d5e866e011ecc45a4d5b20d5e0192997 (patch)
treef3593bac5cc6b934f4e122d8a55d02f8599e8bce /nova
parent5b8133a83939fd552b569c4b034cef43907ea1ce (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.py2
-rw-r--r--nova/exception.py2
-rw-r--r--nova/utils.py22
-rw-r--r--nova/virt/xenapi/vm_utils.py2
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