Use save_and_reraise_exception when reraise exception

This commit fixes neutron core and common codes.

Partial-Bug: #1279813
Change-Id: Id109924c7ff9b4f0d74c23665016a54bfd7dff77
This commit is contained in:
Akihiro Motoki 2014-02-12 23:18:36 +09:00
parent 081c5490a8
commit b3ec1cd657
13 changed files with 120 additions and 102 deletions

View File

@ -35,6 +35,7 @@ from neutron.common import topics
from neutron.common import utils as common_utils from neutron.common import utils as common_utils
from neutron import context from neutron import context
from neutron import manager from neutron import manager
from neutron.openstack.common import excutils
from neutron.openstack.common import importutils from neutron.openstack.common import importutils
from neutron.openstack.common import lockutils from neutron.openstack.common import lockutils
from neutron.openstack.common import log as logging from neutron.openstack.common import log as logging
@ -302,14 +303,13 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback, manager.Manager):
try: try:
return self.plugin_rpc.get_external_network_id(self.context) return self.plugin_rpc.get_external_network_id(self.context)
except rpc_common.RemoteError as e: except rpc_common.RemoteError as e:
if e.exc_type == 'TooManyExternalNetworks': with excutils.save_and_reraise_exception():
msg = _( if e.exc_type == 'TooManyExternalNetworks':
"The 'gateway_external_network_id' option must be " msg = _(
"configured for this agent as Neutron has more than " "The 'gateway_external_network_id' option must be "
"one external network.") "configured for this agent as Neutron has more than "
raise Exception(msg) "one external network.")
else: raise Exception(msg)
raise
def _router_added(self, router_id, router): def _router_added(self, router_id, router):
ri = RouterInfo(router_id, self.root_helper, ri = RouterInfo(router_id, self.root_helper,

View File

@ -28,6 +28,7 @@ from eventlet.green import subprocess
from eventlet import greenthread from eventlet import greenthread
from neutron.common import utils from neutron.common import utils
from neutron.openstack.common import excutils
from neutron.openstack.common import log as logging from neutron.openstack.common import log as logging
@ -116,10 +117,11 @@ def find_child_pids(pid):
try: try:
raw_pids = execute(['ps', '--ppid', pid, '-o', 'pid=']) raw_pids = execute(['ps', '--ppid', pid, '-o', 'pid='])
except RuntimeError as e: except RuntimeError as e:
# Exception has already been logged by execute
no_children_found = 'Exit code: 1' in str(e)
if no_children_found:
return []
# Unexpected errors are the responsibility of the caller # Unexpected errors are the responsibility of the caller
raise with excutils.save_and_reraise_exception() as ctxt:
# Exception has already been logged by execute
no_children_found = 'Exit code: 1' in str(e)
if no_children_found:
ctxt.reraise = False
return []
return [x.strip() for x in raw_pids.split('\n') if x.strip()] return [x.strip() for x in raw_pids.split('\n') if x.strip()]

View File

@ -35,6 +35,7 @@ from neutron.common import constants as n_const
from neutron.common import topics from neutron.common import topics
from neutron.common import utils from neutron.common import utils
from neutron import context from neutron import context
from neutron.openstack.common import excutils
from neutron.openstack.common import log as logging from neutron.openstack.common import log as logging
from neutron.openstack.common import loopingcall from neutron.openstack.common import loopingcall
from neutron.openstack.common import service from neutron.openstack.common import service
@ -255,8 +256,9 @@ class UnixDomainMetadataProxy(object):
try: try:
os.unlink(cfg.CONF.metadata_proxy_socket) os.unlink(cfg.CONF.metadata_proxy_socket)
except OSError: except OSError:
if os.path.exists(cfg.CONF.metadata_proxy_socket): with excutils.save_and_reraise_exception() as ctxt:
raise if not os.path.exists(cfg.CONF.metadata_proxy_socket):
ctxt.reraise = False
else: else:
os.makedirs(dirname, 0o755) os.makedirs(dirname, 0o755)

View File

@ -19,6 +19,8 @@
Neutron base exception handling. Neutron base exception handling.
""" """
from neutron.openstack.common import excutils
class NeutronException(Exception): class NeutronException(Exception):
"""Base Neutron Exception. """Base Neutron Exception.
@ -34,11 +36,11 @@ class NeutronException(Exception):
super(NeutronException, self).__init__(self.message % kwargs) super(NeutronException, self).__init__(self.message % kwargs)
self.msg = self.message % kwargs self.msg = self.message % kwargs
except Exception: except Exception:
if self.use_fatal_exceptions(): with excutils.save_and_reraise_exception() as ctxt:
raise if not self.use_fatal_exceptions():
else: ctxt.reraise = False
# at least get the core message out if something happened # at least get the core message out if something happened
super(NeutronException, self).__init__(self.message) super(NeutronException, self).__init__(self.message)
def __unicode__(self): def __unicode__(self):
return unicode(self.msg) return unicode(self.msg)

View File

@ -26,6 +26,7 @@ from neutron.db import models_v2
from neutron.extensions import agent as ext_agent from neutron.extensions import agent as ext_agent
from neutron import manager from neutron import manager
from neutron.openstack.common.db import exception as db_exc from neutron.openstack.common.db import exception as db_exc
from neutron.openstack.common import excutils
from neutron.openstack.common import jsonutils from neutron.openstack.common import jsonutils
from neutron.openstack.common import log as logging from neutron.openstack.common import log as logging
from neutron.openstack.common import timeutils from neutron.openstack.common import timeutils
@ -178,21 +179,22 @@ class AgentDbMixin(ext_agent.AgentPluginBase):
try: try:
return self._create_or_update_agent(context, agent) return self._create_or_update_agent(context, agent)
except db_exc.DBDuplicateEntry as e: except db_exc.DBDuplicateEntry as e:
if e.columns == ['agent_type', 'host']: with excutils.save_and_reraise_exception() as ctxt:
# It might happen that two or more concurrent transactions are if e.columns == ['agent_type', 'host']:
# trying to insert new rows having the same value of # It might happen that two or more concurrent transactions
# (agent_type, host) pair at the same time (if there has been # are trying to insert new rows having the same value of
# no such entry in the table and multiple agent status updates # (agent_type, host) pair at the same time (if there has
# are being processed at the moment). In this case having a # been no such entry in the table and multiple agent status
# unique constraint on (agent_type, host) columns guarantees # updates are being processed at the moment). In this case
# that only one transaction will succeed and insert a new agent # having a unique constraint on (agent_type, host) columns
# entry, others will fail and be rolled back. That means we # guarantees that only one transaction will succeed and
# must retry them one more time: no INSERTs will be issued, # insert a new agent entry, others will fail and be rolled
# because _get_agent_by_type_and_host() will return the # back. That means we must retry them one more time: no
# existing agent entry, which will be updated multiple times # INSERTs will be issued, because
return self._create_or_update_agent(context, agent) # _get_agent_by_type_and_host() will return the existing
# agent entry, which will be updated multiple times
raise ctxt.reraise = False
return self._create_or_update_agent(context, agent)
class AgentExtRpcCallback(object): class AgentExtRpcCallback(object):

View File

@ -22,6 +22,7 @@ from neutron.common import utils
from neutron.extensions import portbindings from neutron.extensions import portbindings
from neutron import manager from neutron import manager
from neutron.openstack.common.db import exception as db_exc from neutron.openstack.common.db import exception as db_exc
from neutron.openstack.common import excutils
from neutron.openstack.common import log as logging from neutron.openstack.common import log as logging
@ -58,20 +59,22 @@ class DhcpRpcCallbackMixin(object):
raise n_exc.Invalid(message=msg) raise n_exc.Invalid(message=msg)
except (db_exc.DBError, n_exc.NetworkNotFound, except (db_exc.DBError, n_exc.NetworkNotFound,
n_exc.SubnetNotFound, n_exc.IpAddressGenerationFailure) as e: n_exc.SubnetNotFound, n_exc.IpAddressGenerationFailure) as e:
if isinstance(e, n_exc.IpAddressGenerationFailure): with excutils.save_and_reraise_exception() as ctxt:
# Check if the subnet still exists and if it does not, this is ctxt.reraise = False
# the reason why the ip address generation failed. In any other if isinstance(e, n_exc.IpAddressGenerationFailure):
# unlikely event re-raise # Check if the subnet still exists and if it does not,
try: # this is the reason why the ip address generation failed.
subnet_id = port['port']['fixed_ips'][0]['subnet_id'] # In any other unlikely event re-raise
plugin.get_subnet(context, subnet_id) try:
except n_exc.SubnetNotFound: subnet_id = port['port']['fixed_ips'][0]['subnet_id']
pass plugin.get_subnet(context, subnet_id)
else: except n_exc.SubnetNotFound:
raise pass
network_id = port['port']['network_id'] else:
LOG.warn(_("Port for network %(net_id)s could not be created: " ctxt.reraise = True
"%(reason)s") % {"net_id": network_id, 'reason': e}) network_id = port['port']['network_id']
LOG.warn(_("Port for network %(net_id)s could not be created: "
"%(reason)s") % {"net_id": network_id, 'reason': e})
def get_active_networks(self, context, **kwargs): def get_active_networks(self, context, **kwargs):
"""Retrieve and return a list of the active network ids.""" """Retrieve and return a list of the active network ids."""

View File

@ -30,6 +30,7 @@ from neutron.extensions import loadbalancer
from neutron.extensions.loadbalancer import LoadBalancerPluginBase from neutron.extensions.loadbalancer import LoadBalancerPluginBase
from neutron import manager from neutron import manager
from neutron.openstack.common.db import exception from neutron.openstack.common.db import exception
from neutron.openstack.common import excutils
from neutron.openstack.common import log as logging from neutron.openstack.common import log as logging
from neutron.openstack.common import uuidutils from neutron.openstack.common import uuidutils
from neutron.plugins.common import constants from neutron.plugins.common import constants
@ -204,16 +205,15 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase,
try: try:
r = self._get_by_id(context, model, id) r = self._get_by_id(context, model, id)
except exc.NoResultFound: except exc.NoResultFound:
if issubclass(model, Vip): with excutils.save_and_reraise_exception():
raise loadbalancer.VipNotFound(vip_id=id) if issubclass(model, Vip):
elif issubclass(model, Pool): raise loadbalancer.VipNotFound(vip_id=id)
raise loadbalancer.PoolNotFound(pool_id=id) elif issubclass(model, Pool):
elif issubclass(model, Member): raise loadbalancer.PoolNotFound(pool_id=id)
raise loadbalancer.MemberNotFound(member_id=id) elif issubclass(model, Member):
elif issubclass(model, HealthMonitor): raise loadbalancer.MemberNotFound(member_id=id)
raise loadbalancer.HealthMonitorNotFound(monitor_id=id) elif issubclass(model, HealthMonitor):
else: raise loadbalancer.HealthMonitorNotFound(monitor_id=id)
raise
return r return r
def assert_modification_allowed(self, obj): def assert_modification_allowed(self, obj):

View File

@ -32,6 +32,7 @@ from neutron.db import models_v2
from neutron.extensions import vpnaas from neutron.extensions import vpnaas
from neutron.extensions.vpnaas import VPNPluginBase from neutron.extensions.vpnaas import VPNPluginBase
from neutron import manager from neutron import manager
from neutron.openstack.common import excutils
from neutron.openstack.common import log as logging from neutron.openstack.common import log as logging
from neutron.openstack.common import uuidutils from neutron.openstack.common import uuidutils
from neutron.plugins.common import constants from neutron.plugins.common import constants
@ -178,18 +179,17 @@ class VPNPluginDb(VPNPluginBase, base_db.CommonDbMixin):
try: try:
r = self._get_by_id(context, model, v_id) r = self._get_by_id(context, model, v_id)
except exc.NoResultFound: except exc.NoResultFound:
if issubclass(model, IPsecSiteConnection): with excutils.save_and_reraise_exception():
raise vpnaas.IPsecSiteConnectionNotFound( if issubclass(model, IPsecSiteConnection):
ipsec_site_conn_id=v_id raise vpnaas.IPsecSiteConnectionNotFound(
) ipsec_site_conn_id=v_id
elif issubclass(model, IKEPolicy): )
raise vpnaas.IKEPolicyNotFound(ikepolicy_id=v_id) elif issubclass(model, IKEPolicy):
elif issubclass(model, IPsecPolicy): raise vpnaas.IKEPolicyNotFound(ikepolicy_id=v_id)
raise vpnaas.IPsecPolicyNotFound(ipsecpolicy_id=v_id) elif issubclass(model, IPsecPolicy):
elif issubclass(model, VPNService): raise vpnaas.IPsecPolicyNotFound(ipsecpolicy_id=v_id)
raise vpnaas.VPNServiceNotFound(vpnservice_id=v_id) elif issubclass(model, VPNService):
else: raise vpnaas.VPNServiceNotFound(vpnservice_id=v_id)
raise
return r return r
def assert_update_allowed(self, obj): def assert_update_allowed(self, obj):

View File

@ -27,6 +27,7 @@ from neutron.api.v2 import attributes
from neutron.common import exceptions from neutron.common import exceptions
import neutron.common.utils as utils import neutron.common.utils as utils
from neutron import manager from neutron import manager
from neutron.openstack.common import excutils
from neutron.openstack.common import importutils from neutron.openstack.common import importutils
from neutron.openstack.common import log as logging from neutron.openstack.common import log as logging
from neutron.openstack.common import policy from neutron.openstack.common import policy
@ -274,8 +275,8 @@ class OwnerCheck(policy.Check):
fields=[parent_field]) fields=[parent_field])
target[self.target_field] = data[parent_field] target[self.target_field] = data[parent_field]
except Exception: except Exception:
LOG.exception(_('Policy check error while calling %s!'), f) with excutils.save_and_reraise_exception():
raise LOG.exception(_('Policy check error while calling %s!'), f)
match = self.match % target match = self.match % target
if self.kind in creds: if self.kind in creds:
return match == unicode(creds[self.kind]) return match == unicode(creds[self.kind])

View File

@ -25,6 +25,7 @@ from oslo.config import cfg
from neutron.common import config from neutron.common import config
from neutron.common import legacy from neutron.common import legacy
from neutron import context from neutron import context
from neutron.openstack.common import excutils
from neutron.openstack.common import importutils from neutron.openstack.common import importutils
from neutron.openstack.common import log as logging from neutron.openstack.common import log as logging
from neutron.openstack.common import loopingcall from neutron.openstack.common import loopingcall
@ -102,8 +103,9 @@ def serve_wsgi(cls):
service = cls.create('quantum') service = cls.create('quantum')
service.start() service.start()
except Exception: except Exception:
LOG.exception(_('Unrecoverable error: please check log for details.')) with excutils.save_and_reraise_exception():
raise LOG.exception(_('Unrecoverable error: please check log '
'for details.'))
return service return service

View File

@ -27,6 +27,7 @@ from neutron.agent.linux import ip_lib
from neutron.agent.linux import utils from neutron.agent.linux import utils
from neutron.common import exceptions from neutron.common import exceptions
from neutron.common import utils as n_utils from neutron.common import utils as n_utils
from neutron.openstack.common import excutils
from neutron.openstack.common import importutils from neutron.openstack.common import importutils
from neutron.openstack.common import log as logging from neutron.openstack.common import log as logging
from neutron.plugins.common import constants from neutron.plugins.common import constants
@ -65,10 +66,10 @@ class HaproxyNSDriver(agent_device_driver.AgentDeviceDriver):
try: try:
vif_driver = importutils.import_object(conf.interface_driver, conf) vif_driver = importutils.import_object(conf.interface_driver, conf)
except ImportError: except ImportError:
msg = (_('Error importing interface driver: %s') with excutils.save_and_reraise_exception():
% conf.haproxy.interface_driver) msg = (_('Error importing interface driver: %s')
LOG.error(msg) % conf.haproxy.interface_driver)
raise LOG.error(msg)
self.vif_driver = vif_driver self.vif_driver = vif_driver
self.plugin_rpc = plugin_rpc self.plugin_rpc = plugin_rpc

View File

@ -21,6 +21,7 @@ import six
from neutron.api import extensions from neutron.api import extensions
from neutron.db import servicetype_db as sdb from neutron.db import servicetype_db as sdb
from neutron.openstack.common import excutils
from neutron.openstack.common import importutils from neutron.openstack.common import importutils
from neutron.openstack.common import log as logging from neutron.openstack.common import log as logging
from neutron.services import provider_configuration as pconf from neutron.services import provider_configuration as pconf
@ -84,11 +85,11 @@ def load_drivers(service_type, plugin):
{'provider': provider['driver'], {'provider': provider['driver'],
'service_type': service_type}) 'service_type': service_type})
except ImportError: except ImportError:
LOG.exception(_("Error loading provider '%(provider)s' for " with excutils.save_and_reraise_exception():
"service %(service_type)s"), LOG.exception(_("Error loading provider '%(provider)s' for "
{'provider': provider['driver'], "service %(service_type)s"),
'service_type': service_type}) {'provider': provider['driver'],
raise 'service_type': service_type})
default_provider = None default_provider = None
try: try:

View File

@ -40,6 +40,7 @@ from neutron.common import constants
from neutron.common import exceptions as exception from neutron.common import exceptions as exception
from neutron import context from neutron import context
from neutron.openstack.common.db.sqlalchemy import session from neutron.openstack.common.db.sqlalchemy import session
from neutron.openstack.common import excutils
from neutron.openstack.common import gettextutils from neutron.openstack.common import gettextutils
from neutron.openstack.common import jsonutils from neutron.openstack.common import jsonutils
from neutron.openstack.common import log as logging from neutron.openstack.common import log as logging
@ -176,9 +177,10 @@ class Server(object):
sock = wrap_ssl(sock) sock = wrap_ssl(sock)
except socket.error as err: except socket.error as err:
if err.errno != errno.EADDRINUSE: with excutils.save_and_reraise_exception() as ctxt:
raise if err.errno == errno.EADDRINUSE:
eventlet.sleep(0.1) ctxt.reraise = False
eventlet.sleep(0.1)
if not sock: if not sock:
raise RuntimeError(_("Could not bind to %(host)s:%(port)s " raise RuntimeError(_("Could not bind to %(host)s:%(port)s "
"after trying for %(time)d seconds") % "after trying for %(time)d seconds") %
@ -698,19 +700,18 @@ class XMLDeserializer(TextDeserializer):
return result return result
return dict({root_tag: result}, **links) return dict({root_tag: result}, **links)
except Exception as e: except Exception as e:
parseError = False with excutils.save_and_reraise_exception():
# Python2.7 parseError = False
if (hasattr(etree, 'ParseError') and # Python2.7
isinstance(e, getattr(etree, 'ParseError'))): if (hasattr(etree, 'ParseError') and
parseError = True isinstance(e, getattr(etree, 'ParseError'))):
# Python2.6 parseError = True
elif isinstance(e, expat.ExpatError): # Python2.6
parseError = True elif isinstance(e, expat.ExpatError):
if parseError: parseError = True
msg = _("Cannot understand XML") if parseError:
raise exception.MalformedRequestBody(reason=msg) msg = _("Cannot understand XML")
else: raise exception.MalformedRequestBody(reason=msg)
raise
def _from_xml_node(self, node, listnames): def _from_xml_node(self, node, listnames):
"""Convert a minidom node to a simple Python type. """Convert a minidom node to a simple Python type.
@ -832,8 +833,9 @@ class RequestDeserializer(object):
try: try:
deserializer = self.get_body_deserializer(content_type) deserializer = self.get_body_deserializer(content_type)
except exception.InvalidContentType: except exception.InvalidContentType:
LOG.debug(_("Unable to deserialize body as provided Content-Type")) with excutils.save_and_reraise_exception():
raise LOG.debug(_("Unable to deserialize body as provided "
"Content-Type"))
return deserializer.deserialize(request.body, action) return deserializer.deserialize(request.body, action)