diff options
author | Håvard Pettersen <havardpe@oath.com> | 2021-10-12 09:23:22 +0000 |
---|---|---|
committer | Håvard Pettersen <havardpe@oath.com> | 2021-10-12 09:24:31 +0000 |
commit | 555766f3e9b0d2898870f5e9f9c29e4b337aa7da (patch) | |
tree | e2e83d35a96c3f7e61f73e30fb086d118b8e09e2 /vespalib | |
parent | 7287be4ea675f2fce66bdc528b56719b56079e4c (diff) |
central classification of 'unsafe' exceptions
Diffstat (limited to 'vespalib')
-rw-r--r-- | vespalib/src/tests/exception_classes/exception_classes_test.cpp | 19 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/exceptions.cpp | 14 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/exceptions.h | 17 |
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); + } |