summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Harlow <harlowja@yahoo-inc.com>2016-01-22 10:21:27 -0800
committerJoshua Harlow <harlowja@yahoo-inc.com>2016-01-22 10:36:56 -0800
commit9f3fbea48aa604df503b4920fdb81262be548521 (patch)
treec621ab1dae8b9ffe3c33cc435ff443eb73935286
parent9d58253588401113ee62fffd049e4471f3cebc38 (diff)
downloadoslo-utils-9f3fbea48aa604df503b4920fdb81262be548521.tar.gz
Add excutils.save_and_reraise_exception force_reraise + capture
Change-Id: Ie0972ca5634547ce3a71f7755905d3081008a2f8
-rw-r--r--oslo_utils/excutils.py22
-rw-r--r--oslo_utils/tests/test_excutils.py33
2 files changed, 52 insertions, 3 deletions
diff --git a/oslo_utils/excutils.py b/oslo_utils/excutils.py
index dbaf0f6..0d1517b 100644
--- a/oslo_utils/excutils.py
+++ b/oslo_utils/excutils.py
@@ -178,10 +178,26 @@ class save_and_reraise_exception(object):
if logger is None:
logger = logging.getLogger()
self.logger = logger
+ self.type_, self.value, self.tb = (None, None, None)
+
+ def force_reraise(self):
+ if self.type_ is None and self.value is None:
+ raise RuntimeError("There is no (currently) captured exception"
+ " to force the reraising of")
+ six.reraise(self.type_, self.value, self.tb)
+
+ def capture(self, check=True):
+ (type_, value, tb) = sys.exc_info()
+ if check and type_ is None and value is None:
+ raise RuntimeError("There is no active exception to capture")
+ self.type_, self.value, self.tb = (type_, value, tb)
+ return self
def __enter__(self):
- self.type_, self.value, self.tb, = sys.exc_info()
- return self
+ # TODO(harlowja): perhaps someday in the future turn check here
+ # to true, because that is likely the desired intention, and doing
+ # so ensures that people are actually using this correctly.
+ return self.capture(check=False)
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type is not None:
@@ -192,7 +208,7 @@ class save_and_reraise_exception(object):
self.tb))
return False
if self.reraise:
- six.reraise(self.type_, self.value, self.tb)
+ self.force_reraise()
def forever_retry_uncaught_exceptions(infunc):
diff --git a/oslo_utils/tests/test_excutils.py b/oslo_utils/tests/test_excutils.py
index 60f752d..197bdb6 100644
--- a/oslo_utils/tests/test_excutils.py
+++ b/oslo_utils/tests/test_excutils.py
@@ -62,6 +62,39 @@ class CausedByTest(test_base.BaseTestCase):
class SaveAndReraiseTest(test_base.BaseTestCase):
+ def test_save_and_reraise_exception_forced(self):
+
+ def _force_reraise():
+ try:
+ raise IOError("I broke")
+ except Exception:
+ with excutils.save_and_reraise_exception() as e:
+ e.reraise = False
+ e.force_reraise()
+
+ self.assertRaises(IOError, _force_reraise)
+
+ def test_save_and_reraise_exception_capture_reraise(self):
+
+ def _force_reraise():
+ try:
+ raise IOError("I broke")
+ except Exception:
+ excutils.save_and_reraise_exception().capture().force_reraise()
+
+ self.assertRaises(IOError, _force_reraise)
+
+ def test_save_and_reraise_exception_capture_not_active(self):
+ e = excutils.save_and_reraise_exception()
+ self.assertRaises(RuntimeError, e.capture, check=True)
+
+ def test_save_and_reraise_exception_forced_not_active(self):
+ e = excutils.save_and_reraise_exception()
+ self.assertRaises(RuntimeError, e.force_reraise)
+ e = excutils.save_and_reraise_exception()
+ e.capture(check=False)
+ self.assertRaises(RuntimeError, e.force_reraise)
+
def test_save_and_reraise_exception(self):
e = None
msg = 'foo'