From 616098dcd36b20e01d38898b8942003df664e6ac Mon Sep 17 00:00:00 2001 From: Boris Pavlovic Date: Fri, 14 Jun 2013 17:53:53 +0400 Subject: [PATCH] Do not raise NEW exceptions Raising NEW exception is bad practice, because we lose TraceBack. So all places like: except SomeException as e: raise e should be replaced by except SomeException: raise If we are doing some other actions before reraising we should store information about exception then do all actions and then reraise it. This is caused by eventlet bug. It lost information about exception if it switch threads. fixes bug 1191730 Change-Id: Ia375ecef9f16bda65d5146d14ed4b37a988abb0c --- .../openstack/compute/contrib/coverage_ext.py | 3 +- nova/exception.py | 6 ++- nova/network/security_group/quantum_driver.py | 49 +++++++++++-------- nova/tests/utils.py | 2 +- nova/virt/baremetal/db/sqlalchemy/api.py | 3 +- nova/virt/disk/vfs/localfs.py | 8 +-- 6 files changed, 41 insertions(+), 30 deletions(-) diff --git a/nova/api/openstack/compute/contrib/coverage_ext.py b/nova/api/openstack/compute/contrib/coverage_ext.py index 154699470bda..578e2e79d5b6 100644 --- a/nova/api/openstack/compute/contrib/coverage_ext.py +++ b/nova/api/openstack/compute/contrib/coverage_ext.py @@ -134,11 +134,12 @@ class CoverageController(object): # doesn't resolve to 127.0.0.1. Currently backdoors only open on # loopback so this is for covering the common single host use case except socket.error as e: + exc_info = sys.exc_info() if 'ECONNREFUSED' in e and service['host'] == self.host: service['telnet'] = telnetlib.Telnet('127.0.0.1', service['port']) else: - raise e + raise exc_info[0], exc_info[1], exc_info[2] self.services.append(service) self._start_coverage_telnet(service['telnet'], service['service']) diff --git a/nova/exception.py b/nova/exception.py index 68cf1f991f92..002e47a38d2f 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -25,6 +25,7 @@ SHOULD include dedicated exception logging. """ import functools +import sys from oslo.config import cfg import webob.exc @@ -127,7 +128,8 @@ class NovaException(Exception): try: message = self.message % kwargs - except Exception as e: + except Exception: + exc_info = sys.exc_info() # kwargs doesn't match a variable in the message # log the issue and the kwargs LOG.exception(_('Exception in string format operation')) @@ -135,7 +137,7 @@ class NovaException(Exception): LOG.error("%s: %s" % (name, value)) if CONF.fatal_exception_format_errors: - raise e + raise exc_info[0], exc_info[1], exc_info[2] else: # at least get the core message out if something happened message = self.message diff --git a/nova/network/security_group/quantum_driver.py b/nova/network/security_group/quantum_driver.py index 7709da9704f2..6e62d796d245 100644 --- a/nova/network/security_group/quantum_driver.py +++ b/nova/network/security_group/quantum_driver.py @@ -17,6 +17,8 @@ # # @author: Aaron Rosen, Nicira Networks, Inc. +import sys + from oslo.config import cfg from quantumclient.common import exceptions as q_exc from quantumclient.quantum import v2_0 as quantumv20 @@ -50,6 +52,7 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase): security_group = quantum.create_security_group( body).get('security_group') except q_exc.QuantumClientException as e: + exc_info = sys.exc_info() LOG.exception(_("Quantum Error creating security group %s"), name) if e.status_code == 401: @@ -57,7 +60,7 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase): # as this error code could be related to bad input or over # quota raise exc.HTTPBadRequest() - raise e + raise exc_info[0], exc_info[1], exc_info[2] return self._convert_to_nova_security_group_format(security_group) def update_security_group(self, context, security_group, @@ -68,6 +71,7 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase): security_group = quantum.update_security_group( security_group['id'], body).get('security_group') except q_exc.QuantumClientException as e: + exc_info = sys.exc_info() LOG.exception(_("Quantum Error updating security group %s"), name) if e.status_code == 401: @@ -75,7 +79,7 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase): # as this error code could be related to bad input or over # quota raise exc.HTTPBadRequest() - raise e + raise exc_info[0], exc_info[1], exc_info[2] return self._convert_to_nova_security_group_format(security_group) def _convert_to_nova_security_group_format(self, security_group): @@ -120,12 +124,13 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase): quantum, 'security_group', name) group = quantum.show_security_group(id).get('security_group') except q_exc.QuantumClientException as e: + exc_info = sys.exc_info() if e.status_code == 404: LOG.debug(_("Quantum security group %s not found"), name) self.raise_not_found(e.message) else: LOG.error(_("Quantum Error: %s"), e) - raise e + raise exc_info[0], exc_info[1], exc_info[2] return self._convert_to_nova_security_group_format(group) @@ -143,9 +148,9 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase): try: security_groups = quantum.list_security_groups(**search_opts).get( 'security_groups') - except q_exc.QuantumClientException as e: - LOG.exception(_("Quantum Error getting security groups")) - raise e + except q_exc.QuantumClientException: + with excutils.save_and_reraise_exception(): + LOG.exception(_("Quantum Error getting security groups")) converted_rules = [] for security_group in security_groups: converted_rules.append( @@ -165,13 +170,14 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase): try: quantum.delete_security_group(security_group['id']) except q_exc.QuantumClientException as e: + exc_info = sys.exc_info() if e.status_code == 404: self.raise_not_found(e.message) elif e.status_code == 409: self.raise_invalid_property(e.message) else: LOG.error(_("Quantum Error: %s"), e) - raise e + raise exc_info[0], exc_info[1], exc_info[2] def add_rules(self, context, id, name, vals): """Add security group rule(s) to security group. @@ -188,13 +194,14 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase): rules = quantum.create_security_group_rule( body).get('security_group_rules') except q_exc.QuantumClientException as e: + exc_info = sys.exc_info() if e.status_code == 409: LOG.exception(_("Quantum Error getting security group %s"), name) self.raise_not_found(e.message) else: LOG.exception(_("Quantum Error:")) - raise e + raise exc_info[0], exc_info[1], exc_info[2] converted_rules = [] for rule in rules: converted_rules.append( @@ -246,9 +253,8 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase): for rule_id in range(0, len(rule_ids)): quantum.delete_security_group_rule(rule_ids.pop()) except q_exc.QuantumClientException as e: - LOG.exception(_("Quantum Error unable to delete %s"), - rule_ids) - raise e + with excutils.save_and_reraise_exception(): + LOG.exception(_("Quantum Error unable to delete %s"), rule_ids) def get_rule(self, context, id): quantum = quantumv2.get_client(context) @@ -256,12 +262,13 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase): rule = quantum.show_security_group_rule( id).get('security_group_rule') except q_exc.QuantumClientException as e: + exc_info = sys.exc_info() if e.status_code == 404: LOG.debug(_("Quantum security group rule %s not found"), id) self.raise_not_found(e.message) else: LOG.error(_("Quantum Error: %s"), e) - raise e + raise exc_info[0], exc_info[1], exc_info[2] return self._convert_to_nova_security_group_rule_format(rule) def get_instances_security_groups_bindings(self, context): @@ -350,19 +357,20 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase): security_group_id = quantumv20.find_resourceid_by_name_or_id( quantum, 'security_group', security_group_name) except q_exc.QuantumClientException as e: + exc_info = sys.exc_info() if e.status_code == 404: msg = ("Security group %s is not found for project %s" % (security_group_name, context.project_id)) self.raise_not_found(msg) else: LOG.exception(_("Quantum Error:")) - raise e + raise exc_info[0], exc_info[1], exc_info[2] params = {'device_id': instance['uuid']} try: ports = quantum.list_ports(**params).get('ports') - except q_exc.QuantumClientException as e: + except q_exc.QuantumClientException: + with excutils.save_and_reraise_exception(): LOG.exception(_("Quantum Error:")) - raise e if not ports: msg = ("instance_id %s could not be found as device id on" @@ -398,19 +406,20 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase): security_group_id = quantumv20.find_resourceid_by_name_or_id( quantum, 'security_group', security_group_name) except q_exc.QuantumClientException as e: + exc_info = sys.exc_info() if e.status_code == 404: msg = ("Security group %s is not found for project %s" % (security_group_name, context.project_id)) self.raise_not_found(msg) else: LOG.exception(_("Quantum Error:")) - raise e + raise exc_info[0], exc_info[1], exc_info[2] params = {'device_id': instance['uuid']} try: ports = quantum.list_ports(**params).get('ports') - except q_exc.QuantumClientException as e: + except q_exc.QuantumClientException: + with excutils.save_and_reraise_exception(): LOG.exception(_("Quantum Error:")) - raise e if not ports: msg = ("instance_id %s could not be found as device id on" @@ -438,8 +447,8 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase): quantum.update_port(port['id'], {'port': updated_port}) found_security_group = True except Exception: - LOG.exception(_("Quantum Error:")) - raise e + with excutils.save_and_reraise_exception(): + LOG.exception(_("Quantum Error:")) if not found_security_group: msg = (_("Security group %(security_group_name)s not assocaited " "with the instance %(instance)s"), diff --git a/nova/tests/utils.py b/nova/tests/utils.py index 994e4f220327..556d1f91d241 100644 --- a/nova/tests/utils.py +++ b/nova/tests/utils.py @@ -212,5 +212,5 @@ def is_ipv6_supported(): if e.errno == errno.EAFNOSUPPORT: has_ipv6_support = False else: - raise e + raise return has_ipv6_support diff --git a/nova/virt/baremetal/db/sqlalchemy/api.py b/nova/virt/baremetal/db/sqlalchemy/api.py index 88d44e3d307a..0012745a5977 100644 --- a/nova/virt/baremetal/db/sqlalchemy/api.py +++ b/nova/virt/baremetal/db/sqlalchemy/api.py @@ -402,8 +402,7 @@ def bm_interface_set_vif_uuid(context, if_id, vif_uuid): if str(e).find('IntegrityError') != -1: raise exception.NovaException(_("Baremetal interface %s " "already in use") % vif_uuid) - else: - raise e + raise @sqlalchemy_api.require_admin_context diff --git a/nova/virt/disk/vfs/localfs.py b/nova/virt/disk/vfs/localfs.py index 10b9a1aa8c1d..73548134048b 100644 --- a/nova/virt/disk/vfs/localfs.py +++ b/nova/virt/disk/vfs/localfs.py @@ -18,6 +18,7 @@ import os import tempfile from nova import exception +from nova.openstack.common import excutils from nova.openstack.common import log as logging from nova import utils from nova.virt.disk.mount import loop @@ -77,10 +78,9 @@ class VFSLocalFS(vfs.VFS): raise exception.NovaException(mount.error) self.mount = mount except Exception as e: - LOG.debug(_("Failed to mount image %(ex)s)") % - {'ex': str(e)}) - self.teardown() - raise e + with excutils.save_and_reraise_exception(): + LOG.debug(_("Failed to mount image %(ex)s)"), {'ex': str(e)}) + self.teardown() def teardown(self): try: