nova.exception.wrap_exception will re-raise some exceptions, but in the process of possibly notifying that an exception has occurred, it may clobber the current exception information. nova.utils.to_primitive in particular (used by the notifier code) will catch and handle an exception clobbering the current exception being handled in wrap_exception. Eventually when using the bare 'raise', it will attempt to raise None resulting a completely different and unhelpful exception.

The patch saves the exception at the beginning of wrap_exception and then re-raises the original exception avoiding the possibility of a clobbered exception.
This commit is contained in:
Johannes Erdfelt 2011-08-08 19:48:07 +00:00 committed by Tarmac
commit 439afc337f

View File

@ -25,6 +25,7 @@ SHOULD include dedicated exception logging.
"""
from functools import wraps
import sys
from nova import log as logging
@ -96,6 +97,10 @@ def wrap_exception(notifier=None, publisher_id=None, event_type=None,
try:
return f(*args, **kw)
except Exception, e:
# Save exception since it can be clobbered during processing
# below before we can re-raise
exc_info = sys.exc_info()
if notifier:
payload = dict(args=args, exception=e)
payload.update(kw)
@ -122,7 +127,9 @@ def wrap_exception(notifier=None, publisher_id=None, event_type=None,
LOG.exception(_('Uncaught exception'))
#logging.error(traceback.extract_stack(exc_traceback))
raise Error(str(e))
raise
# re-raise original exception since it may have been clobbered
raise exc_info[0], exc_info[1], exc_info[2]
return wraps(f)(wrapped)
return inner