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:
parent
ad57a303f1
commit
2f98379357
|
@ -192,11 +192,11 @@ def reverts_task_state(function):
|
|||
try:
|
||||
return function(self, context, *args, **kwargs)
|
||||
except exception.UnexpectedTaskStateError:
|
||||
LOG.exception(_("Possibly task preempted."))
|
||||
# Note(maoy): unexpected task state means the current
|
||||
# task is preempted. Do not clear task state in this
|
||||
# case.
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_("Possibly task preempted."))
|
||||
except Exception:
|
||||
with excutils.save_and_reraise_exception():
|
||||
try:
|
||||
|
@ -788,12 +788,13 @@ class ComputeManager(manager.SchedulerDependentManager):
|
|||
injected_files, admin_password)
|
||||
except exception.InstanceNotFound:
|
||||
# the instance got deleted during the spawn
|
||||
try:
|
||||
self._deallocate_network(context, instance)
|
||||
except Exception:
|
||||
msg = _('Failed to dealloc network for deleted instance')
|
||||
LOG.exception(msg, instance=instance)
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
try:
|
||||
self._deallocate_network(context, instance)
|
||||
except Exception:
|
||||
msg = _('Failed to dealloc network '
|
||||
'for deleted instance')
|
||||
LOG.exception(msg, instance=instance)
|
||||
except exception.UnexpectedTaskStateError as e:
|
||||
actual_task_state = e.kwargs.get('actual', None)
|
||||
if actual_task_state == 'deleting':
|
||||
|
@ -843,8 +844,8 @@ class ComputeManager(manager.SchedulerDependentManager):
|
|||
self._deallocate_network(context, instance)
|
||||
except Exception:
|
||||
# do not attempt retry if network de-allocation failed:
|
||||
self._log_original_error(exc_info, instance_uuid)
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
self._log_original_error(exc_info, instance_uuid)
|
||||
|
||||
try:
|
||||
method_args = (request_spec, admin_password, injected_files,
|
||||
|
@ -1032,9 +1033,9 @@ class ComputeManager(manager.SchedulerDependentManager):
|
|||
conductor_api=self.conductor_api,
|
||||
security_groups=security_groups)
|
||||
except Exception:
|
||||
LOG.exception(_('Instance failed network setup'),
|
||||
instance=instance)
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_('Instance failed network setup'),
|
||||
instance=instance)
|
||||
|
||||
LOG.debug(_('Instance network_info: |%s|'), network_info,
|
||||
instance=instance)
|
||||
|
@ -1046,9 +1047,9 @@ class ComputeManager(manager.SchedulerDependentManager):
|
|||
try:
|
||||
return self._setup_block_device_mapping(context, instance, bdms)
|
||||
except Exception:
|
||||
LOG.exception(_('Instance failed block device setup'),
|
||||
instance=instance)
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_('Instance failed block device setup'),
|
||||
instance=instance)
|
||||
|
||||
def _spawn(self, context, instance, image_meta, network_info,
|
||||
block_device_info, injected_files, admin_password):
|
||||
|
@ -1063,8 +1064,8 @@ class ComputeManager(manager.SchedulerDependentManager):
|
|||
self._legacy_nw_info(network_info),
|
||||
block_device_info)
|
||||
except Exception:
|
||||
LOG.exception(_('Instance failed to spawn'), instance=instance)
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_('Instance failed to spawn'), instance=instance)
|
||||
|
||||
current_power_state = self._get_power_state(context, instance)
|
||||
return self._instance_update(context, instance['uuid'],
|
||||
|
|
|
@ -26,6 +26,7 @@ from oslo.config import cfg
|
|||
from nova import context
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova.openstack.common import excutils
|
||||
from nova.openstack.common import log as logging
|
||||
from nova import paths
|
||||
from nova import utils
|
||||
|
@ -119,8 +120,8 @@ class XVPConsoleProxy(object):
|
|||
with open(CONF.console_xvp_conf, 'w') as cfile:
|
||||
cfile.write(config)
|
||||
except IOError:
|
||||
LOG.exception(_("Failed to write configuration file"))
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_("Failed to write configuration file"))
|
||||
|
||||
def _xvp_stop(self):
|
||||
LOG.debug(_('Stopping xvp'))
|
||||
|
|
|
@ -38,6 +38,7 @@ from pyasn1.type import univ
|
|||
from nova import context
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova.openstack.common import excutils
|
||||
from nova.openstack.common import fileutils
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common import timeutils
|
||||
|
@ -387,8 +388,8 @@ def _sign_csr(csr_text, ca_folder):
|
|||
with open(inbound, 'w') as csrfile:
|
||||
csrfile.write(csr_text)
|
||||
except IOError:
|
||||
LOG.exception(_('Failed to write inbound.csr'))
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_('Failed to write inbound.csr'))
|
||||
|
||||
LOG.debug(_('Flags path: %s'), ca_folder)
|
||||
start = os.getcwd()
|
||||
|
|
|
@ -29,6 +29,7 @@ from oslo.config import cfg
|
|||
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova.openstack.common import excutils
|
||||
from nova.openstack.common import fileutils
|
||||
from nova.openstack.common import importutils
|
||||
from nova.openstack.common import jsonutils
|
||||
|
@ -1405,9 +1406,9 @@ class LinuxBridgeInterfaceDriver(LinuxNetInterfaceDriver):
|
|||
utils.execute('ip', 'link', 'delete', vlan_interface,
|
||||
run_as_root=True, check_exit_code=[0, 2, 254])
|
||||
except exception.ProcessExecutionError:
|
||||
LOG.error(_("Failed unplugging VLAN interface '%s'"),
|
||||
vlan_interface)
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_("Failed unplugging VLAN interface '%s'"),
|
||||
vlan_interface)
|
||||
LOG.debug(_("Unplugged VLAN interface '%s'"), vlan_interface)
|
||||
|
||||
@classmethod
|
||||
|
@ -1511,8 +1512,9 @@ class LinuxBridgeInterfaceDriver(LinuxNetInterfaceDriver):
|
|||
utils.execute('ip', 'link', 'delete', bridge, run_as_root=True,
|
||||
check_exit_code=[0, 2, 254])
|
||||
except exception.ProcessExecutionError:
|
||||
LOG.error(_("Failed unplugging bridge interface '%s'"), bridge)
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_("Failed unplugging bridge interface '%s'"),
|
||||
bridge)
|
||||
|
||||
LOG.debug(_("Unplugged bridge interface '%s'"), bridge)
|
||||
|
||||
|
@ -1710,8 +1712,9 @@ class QuantumLinuxBridgeInterfaceDriver(LinuxNetInterfaceDriver):
|
|||
utils.execute('ip', 'link', 'delete', dev, run_as_root=True,
|
||||
check_exit_code=[0, 2, 254])
|
||||
except exception.ProcessExecutionError:
|
||||
LOG.error(_("Failed unplugging gateway interface '%s'"), dev)
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_("Failed unplugging gateway interface '%s'"),
|
||||
dev)
|
||||
LOG.debug(_("Unplugged gateway interface '%s'"), dev)
|
||||
return dev
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ from nova import context
|
|||
from nova import exception
|
||||
from nova.network import quantumv2
|
||||
from nova.network.security_group import security_group_base
|
||||
from nova.openstack.common import excutils
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common import uuidutils
|
||||
|
||||
|
@ -332,8 +333,8 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase):
|
|||
'port_id': port['id']})
|
||||
quantum.update_port(port['id'], {'port': updated_port})
|
||||
except Exception:
|
||||
LOG.exception(_("Quantum Error:"))
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_("Quantum Error:"))
|
||||
|
||||
@wrap_check_security_groups_policy
|
||||
def remove_from_instance(self, context, instance, security_group_name):
|
||||
|
|
|
@ -26,6 +26,7 @@ from nova import db
|
|||
from nova.image import glance
|
||||
from nova import network
|
||||
from nova.network import model as network_model
|
||||
from nova.openstack.common import excutils
|
||||
from nova.openstack.common import log
|
||||
from nova.openstack.common.notifier import api as notifier_api
|
||||
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,
|
||||
instance_ref)
|
||||
except Exception:
|
||||
LOG.exception(_('Failed to get nw_info'), instance=instance_ref)
|
||||
if ignore_missing_network_data:
|
||||
return
|
||||
raise
|
||||
try:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_('Failed to get nw_info'),
|
||||
instance=instance_ref)
|
||||
except Exception:
|
||||
if ignore_missing_network_data:
|
||||
return
|
||||
raise
|
||||
|
||||
macs = [vif['address'] for vif in nw_info]
|
||||
uuids = [instance_ref["uuid"]]
|
||||
|
|
|
@ -28,6 +28,7 @@ import os
|
|||
|
||||
from oslo.config import cfg
|
||||
|
||||
from nova.openstack.common import excutils
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common import timeutils
|
||||
|
||||
|
@ -66,9 +67,9 @@ class SchedulerOptions(object):
|
|||
try:
|
||||
return os.path.getmtime(filename)
|
||||
except os.error, e:
|
||||
LOG.exception(_("Could not stat scheduler options file "
|
||||
"%(filename)s: '%(e)s'"), locals())
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_("Could not stat scheduler options file "
|
||||
"%(filename)s: '%(e)s'"), locals())
|
||||
|
||||
def _load_file(self, handle):
|
||||
"""Decode the JSON file. Broken out for testing."""
|
||||
|
|
|
@ -714,10 +714,10 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
is_okay = True
|
||||
|
||||
if not is_okay:
|
||||
LOG.error(_("Error from libvirt during destroy. "
|
||||
"Code=%(errcode)s Error=%(e)s") %
|
||||
locals(), instance=instance)
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_("Error from libvirt during destroy. "
|
||||
"Code=%(errcode)s Error=%(e)s") %
|
||||
locals(), instance=instance)
|
||||
|
||||
def _wait_for_destroy(expected_domid):
|
||||
"""Called at an interval until the VM is gone."""
|
||||
|
@ -787,11 +787,11 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
pass
|
||||
virt_dom.undefine()
|
||||
except libvirt.libvirtError as e:
|
||||
errcode = e.get_error_code()
|
||||
LOG.error(_("Error from libvirt during undefine. "
|
||||
"Code=%(errcode)s Error=%(e)s") %
|
||||
locals(), instance=instance)
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
errcode = e.get_error_code()
|
||||
LOG.error(_("Error from libvirt during undefine. "
|
||||
"Code=%(errcode)s Error=%(e)s") %
|
||||
locals(), instance=instance)
|
||||
|
||||
def _cleanup(self, instance, network_info, block_device_info,
|
||||
destroy_disks):
|
||||
|
@ -1667,13 +1667,14 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
"'%(ex)s'") % {'path': dirpath, 'ex': str(e)})
|
||||
hasDirectIO = False
|
||||
else:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_("Error on '%(path)s' while checking "
|
||||
"direct I/O: '%(ex)s'") %
|
||||
{'path': dirpath, 'ex': str(e)})
|
||||
except Exception, e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_("Error on '%(path)s' while checking direct I/O: "
|
||||
"'%(ex)s'") % {'path': dirpath, 'ex': str(e)})
|
||||
raise
|
||||
except Exception, e:
|
||||
LOG.error(_("Error on '%(path)s' while checking direct I/O: "
|
||||
"'%(ex)s'") % {'path': dirpath, 'ex': str(e)})
|
||||
raise
|
||||
finally:
|
||||
try:
|
||||
os.unlink(testfile)
|
||||
|
@ -1850,9 +1851,10 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
try:
|
||||
cdb.make_drive(configdrive_path)
|
||||
except exception.ProcessExecutionError, e:
|
||||
LOG.error(_('Creating config drive failed with error: %s'),
|
||||
e, instance=instance)
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_('Creating config drive failed '
|
||||
'with error: %s'),
|
||||
e, instance=instance)
|
||||
|
||||
# File injection
|
||||
elif CONF.libvirt_inject_partition != -2:
|
||||
|
@ -1892,10 +1894,10 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
use_cow=CONF.use_cow_images,
|
||||
mandatory=('files',))
|
||||
except Exception as e:
|
||||
LOG.error(_('Error injecting data into image '
|
||||
'%(img_id)s (%(e)s)') % locals(),
|
||||
instance=instance)
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_('Error injecting data into image '
|
||||
'%(img_id)s (%(e)s)') % locals(),
|
||||
instance=instance)
|
||||
|
||||
if CONF.libvirt_type == 'uml':
|
||||
libvirt_utils.chown(image('disk').path, 'root')
|
||||
|
@ -2950,9 +2952,9 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
try:
|
||||
ret = self._conn.compareCPU(cpu.to_xml(), 0)
|
||||
except libvirt.libvirtError, e:
|
||||
ret = e.message
|
||||
LOG.error(m % locals())
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
ret = e.message
|
||||
LOG.error(m % locals())
|
||||
|
||||
if ret <= 0:
|
||||
LOG.error(m % locals())
|
||||
|
|
|
@ -34,6 +34,7 @@ import webob.dec
|
|||
import webob.exc
|
||||
|
||||
from nova import exception
|
||||
from nova.openstack.common import excutils
|
||||
from nova.openstack.common import log as logging
|
||||
|
||||
wsgi_opts = [
|
||||
|
@ -175,9 +176,9 @@ class Server(object):
|
|||
CONF.tcp_keepidle)
|
||||
|
||||
except Exception:
|
||||
LOG.error(_("Failed to start %(name)s on %(host)s"
|
||||
":%(port)s with SSL support") % self.__dict__)
|
||||
raise
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_("Failed to start %(name)s on %(host)s"
|
||||
":%(port)s with SSL support") % self.__dict__)
|
||||
|
||||
wsgi_kwargs = {
|
||||
'func': eventlet.wsgi.server,
|
||||
|
|
Loading…
Reference in New Issue