save_and_reraise_exception: make logging respect the reraise parameter

Do not log original exception if reraise is set to False

Closes-Bug: #1291850
Related-Bug: #1288188

Change-Id: Icd5fcba25c2cd549cee70353a7a62d83bfe1255b
This commit is contained in:
Oleg Bondarev 2014-03-13 13:32:09 +04:00 committed by Ben Nemec
parent 0e98afda1b
commit 33a2cee6a6
2 changed files with 48 additions and 14 deletions

View File

@ -49,9 +49,22 @@ class save_and_reraise_exception(object):
decide_if_need_reraise()
if not should_be_reraised:
ctxt.reraise = False
If another exception occurs and reraise flag is False,
the saved exception will not be logged.
If the caller wants to raise new exception during exception handling
he/she sets reraise to False initially with an ability to set it back to
True if needed::
except Exception:
with save_and_reraise_exception(reraise=False) as ctxt:
[if statements to determine whether to raise a new exception]
# Not raising a new exception, so reraise
ctxt.reraise = True
"""
def __init__(self):
self.reraise = True
def __init__(self, reraise=True):
self.reraise = reraise
def __enter__(self):
self.type_, self.value, self.tb, = sys.exc_info()
@ -59,10 +72,11 @@ class save_and_reraise_exception(object):
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type is not None:
logging.error(_LE('Original exception being dropped: %s'),
traceback.format_exception(self.type_,
self.value,
self.tb))
if self.reraise:
logging.error(_LE('Original exception being dropped: %s'),
traceback.format_exception(self.type_,
self.value,
self.tb))
return False
if self.reraise:
six.reraise(self.type_, self.value, self.tb)

View File

@ -15,6 +15,8 @@
import logging
import time
import mock
from openstack.common import excutils
from openstack.common.fixture import moxstubout
from openstack.common import test
@ -42,16 +44,18 @@ class SaveAndReraiseTest(test.BaseTestCase):
def test_save_and_reraise_exception_dropped(self):
e = None
msg = 'second exception'
try:
with mock.patch('logging.error') as log:
try:
raise Exception('dropped')
except Exception:
with excutils.save_and_reraise_exception():
raise Exception(msg)
except Exception as _e:
e = _e
try:
raise Exception('dropped')
except Exception:
with excutils.save_and_reraise_exception():
raise Exception(msg)
except Exception as _e:
e = _e
self.assertEqual(str(e), msg)
self.assertEqual(str(e), msg)
self.assertTrue(log.called)
def test_save_and_reraise_exception_no_reraise(self):
"""Test that suppressing the reraise works."""
@ -61,6 +65,22 @@ class SaveAndReraiseTest(test.BaseTestCase):
with excutils.save_and_reraise_exception() as ctxt:
ctxt.reraise = False
def test_save_and_reraise_exception_dropped_no_reraise(self):
e = None
msg = 'second exception'
with mock.patch('logging.error') as log:
try:
try:
raise Exception('dropped')
except Exception:
with excutils.save_and_reraise_exception(reraise=False):
raise Exception(msg)
except Exception as _e:
e = _e
self.assertEqual(str(e), msg)
self.assertFalse(log.called)
class ForeverRetryUncaughtExceptionsTest(test.BaseTestCase):