From d83342226470e1957525978d7bec7d98db9bb695 Mon Sep 17 00:00:00 2001 From: melanie witt Date: Thu, 18 Jul 2019 23:59:16 +0000 Subject: [PATCH] Avoid logging traceback when detach device not found We use the oslo.utils save_and_reraise_exception context manager in our detach device code and catch specific exceptions that mean 'not found' and raise DeviceNotFound instead. When we do that, the save_and_reraise_exception context manager logs an ERROR traceback of the original exception, for informational purposes. This is misleading when trying to debug other issues, as it makes it look like the caught exception caused a problem. This passes the reraise=False keyword arg to the context manager and sets the 'reraise' attribute to True only if we are not going to raise a different exception. Related-Bug: #1836212 Change-Id: Icce1e31fe3ebcbf9e4897bbfa57b7f3d1fba67a3 (cherry picked from commit 738774b942dab21d8c03c70b4e74b6a487515ff5) --- nova/tests/unit/virt/libvirt/test_guest.py | 5 +++++ nova/virt/libvirt/guest.py | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/nova/tests/unit/virt/libvirt/test_guest.py b/nova/tests/unit/virt/libvirt/test_guest.py index cf363557a8b2..8d45ec66abb6 100644 --- a/nova/tests/unit/virt/libvirt/test_guest.py +++ b/nova/tests/unit/virt/libvirt/test_guest.py @@ -327,6 +327,11 @@ class GuestTestCase(test.NoDBTestCase): inc_sleep_time=.01, max_retry_count=3) # Some time later, we can do the wait/retry to ensure detach self.assertRaises(exception.DeviceNotFound, retry_detach) + # Check that the save_and_reraise_exception context manager didn't log + # a traceback when the libvirtError was caught and DeviceNotFound was + # raised. + self.assertNotIn('Original exception being dropped', + self.stdlog.logger.output) @mock.patch.object(libvirt_guest.Guest, "detach_device") def test_detach_device_with_retry_operation_internal(self, mock_detach): diff --git a/nova/virt/libvirt/guest.py b/nova/virt/libvirt/guest.py index 561febf70e8e..8da7015e4e3f 100644 --- a/nova/virt/libvirt/guest.py +++ b/nova/virt/libvirt/guest.py @@ -404,7 +404,7 @@ class Guest(object): device, persistent, live) except libvirt.libvirtError as ex: - with excutils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(reraise=False) as ctx: errcode = ex.get_error_code() if errcode in (libvirt.VIR_ERR_OPERATION_FAILED, libvirt.VIR_ERR_INTERNAL_ERROR): @@ -421,6 +421,10 @@ class Guest(object): # detach fails because the device is not found raise exception.DeviceNotFound( device=alternative_device_name) + # Re-raise the original exception if we're not raising + # DeviceNotFound instead. This will avoid logging of a + # "Original exception being dropped" traceback. + ctx.reraise = True conf = get_device_conf_func(device) if conf is None: