aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2021-10-12 09:23:22 +0000
committerHåvard Pettersen <havardpe@oath.com>2021-10-12 09:24:31 +0000
commit555766f3e9b0d2898870f5e9f9c29e4b337aa7da (patch)
treee2e83d35a96c3f7e61f73e30fb086d118b8e09e2 /vespalib
parent7287be4ea675f2fce66bdc528b56719b56079e4c (diff)
central classification of 'unsafe' exceptions
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/tests/exception_classes/exception_classes_test.cpp19
-rw-r--r--vespalib/src/vespa/vespalib/util/exceptions.cpp14
-rw-r--r--vespalib/src/vespa/vespalib/util/exceptions.h17
3 files changed, 50 insertions, 0 deletions
diff --git a/vespalib/src/tests/exception_classes/exception_classes_test.cpp b/vespalib/src/tests/exception_classes/exception_classes_test.cpp
index 2741fe20161..ffe0f21ceb8 100644
--- a/vespalib/src/tests/exception_classes/exception_classes_test.cpp
+++ b/vespalib/src/tests/exception_classes/exception_classes_test.cpp
@@ -47,4 +47,23 @@ TEST("test that OOMException carries message forward.") {
EXPECT_TRUE(caught);
}
+TEST("require that rethrow_if_unsafe will rethrow unsafe exception") {
+ try {
+ try {
+ throw OOMException("my message");
+ } catch (const std::exception &e) {
+ rethrow_if_unsafe(e);
+ TEST_ERROR("should not be reached");
+ }
+ } catch (const OOMException &) {}
+}
+
+TEST("require that rethrow_if_unsafe will not rethrow safe exception") {
+ try {
+ throw IllegalArgumentException("my message");
+ } catch (const std::exception &e) {
+ rethrow_if_unsafe(e);
+ }
+}
+
TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/vespalib/src/vespa/vespalib/util/exceptions.cpp b/vespalib/src/vespa/vespalib/util/exceptions.cpp
index 8fb50a9403c..2c21ab8bcea 100644
--- a/vespalib/src/vespa/vespalib/util/exceptions.cpp
+++ b/vespalib/src/vespa/vespalib/util/exceptions.cpp
@@ -186,4 +186,18 @@ IoException::getErrorType(int error) {
}
}
+template <typename T>
+bool check_type(const std::exception &e) {
+ return (dynamic_cast<const T *>(&e) != nullptr);
+}
+
+void rethrow_if_unsafe(const std::exception &e) {
+ if (check_type<std::bad_alloc>(e) ||
+ check_type<OOMException>(e) ||
+ check_type<FatalException>(e))
+ {
+ throw;
+ }
+}
+
} // vespalib
diff --git a/vespalib/src/vespa/vespalib/util/exceptions.h b/vespalib/src/vespa/vespalib/util/exceptions.h
index c1afaf0122a..8c470d25a5b 100644
--- a/vespalib/src/vespa/vespalib/util/exceptions.h
+++ b/vespalib/src/vespa/vespalib/util/exceptions.h
@@ -154,5 +154,22 @@ private:
std::terminate_handler _oldTerminate;
};
+/**
+ * NOTE: This function must only be called from within a catch block,
+ * and the parameter must reference the caught exception.
+ *
+ * Based on the run-time type of the exception, determine if it is
+ * safe to handle this exception and continue normal program
+ * operation. If the exception is considered safe, no additional
+ * action is taken. If the exception is considered unsafe, it will be
+ * re-thrown.
+ *
+ * Unsafe exceptions fall under two categories; exceptions that are
+ * specifically designed to end program execution and exceptions that
+ * have an elevated chance of causing issues when being thrown across
+ * code that is not completely exception safe.
+ **/
+void rethrow_if_unsafe(const std::exception &e);
+
}