Fix issues with re-raising exceptions.

There is complication with re-raising exceptions and our usage of
eventlet.  If the code in the exception handler accesses the db or rpc
in the exception handler, it will no longer be able to re-raise the
exception.  Using excutils.save_and_reraise_exception() works aorund
this issue.

The most common error is calling LOG.error() or LOG.exception(), as it
is possible for these to go access rpc.  There is an option to turn on
notifications for these errors.

Fix bug 845866.

Change-Id: Icfca2af63805711229249aa7abe60a938edd1b35
This commit is contained in:
Russell Bryant
2013-03-05 10:55:18 -05:00
parent 93ab0b2fe8
commit 5d459bf23b
3 changed files with 17 additions and 10 deletions

View File

@@ -26,6 +26,7 @@ from nova import db
from nova.image import glance from nova.image import glance
from nova import network from nova import network
from nova.network import model as network_model from nova.network import model as network_model
from nova.openstack.common import excutils
from nova.openstack.common import log from nova.openstack.common import log
from nova.openstack.common.notifier import api as notifier_api from nova.openstack.common.notifier import api as notifier_api
from nova.openstack.common import timeutils from nova.openstack.common import timeutils
@@ -225,10 +226,14 @@ def bandwidth_usage(instance_ref, audit_start,
nw_info = network.API().get_instance_nw_info(admin_context, nw_info = network.API().get_instance_nw_info(admin_context,
instance_ref) instance_ref)
except Exception: except Exception:
LOG.exception(_('Failed to get nw_info'), instance=instance_ref) try:
if ignore_missing_network_data: with excutils.save_and_reraise_exception():
return LOG.exception(_('Failed to get nw_info'),
raise instance=instance_ref)
except Exception:
if ignore_missing_network_data:
return
raise
macs = [vif['address'] for vif in nw_info] macs = [vif['address'] for vif in nw_info]
uuids = [instance_ref["uuid"]] uuids = [instance_ref["uuid"]]

View File

@@ -28,6 +28,7 @@ import os
from oslo.config import cfg from oslo.config import cfg
from nova.openstack.common import excutils
from nova.openstack.common import log as logging from nova.openstack.common import log as logging
from nova.openstack.common import timeutils from nova.openstack.common import timeutils
@@ -66,9 +67,9 @@ class SchedulerOptions(object):
try: try:
return os.path.getmtime(filename) return os.path.getmtime(filename)
except os.error, e: except os.error, e:
LOG.exception(_("Could not stat scheduler options file " with excutils.save_and_reraise_exception():
"%(filename)s: '%(e)s'"), locals()) LOG.exception(_("Could not stat scheduler options file "
raise "%(filename)s: '%(e)s'"), locals())
def _load_file(self, handle): def _load_file(self, handle):
"""Decode the JSON file. Broken out for testing.""" """Decode the JSON file. Broken out for testing."""

View File

@@ -34,6 +34,7 @@ import webob.dec
import webob.exc import webob.exc
from nova import exception from nova import exception
from nova.openstack.common import excutils
from nova.openstack.common import log as logging from nova.openstack.common import log as logging
wsgi_opts = [ wsgi_opts = [
@@ -175,9 +176,9 @@ class Server(object):
CONF.tcp_keepidle) CONF.tcp_keepidle)
except Exception: except Exception:
LOG.error(_("Failed to start %(name)s on %(host)s" with excutils.save_and_reraise_exception():
":%(port)s with SSL support") % self.__dict__) LOG.error(_("Failed to start %(name)s on %(host)s"
raise ":%(port)s with SSL support") % self.__dict__)
wsgi_kwargs = { wsgi_kwargs = {
'func': eventlet.wsgi.server, 'func': eventlet.wsgi.server,