Skip to content

Commit 40d9df7

Browse files
committed
iox-#1613 Extend error handling design document and add example code
1 parent f5c0737 commit 40d9df7

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

doc/design/error-handling.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,23 @@ auto errorFunc = [](Error& error) {
264264
func(arg).and_then(successFunc).or_else(errorFunc);
265265
```
266266
267+
### Testing fatal error
268+
269+
For fatal errors the error handler will terminate the execution of the binary. In order to test these paths the
270+
`iox::testing::IOX_EXPECT_FATAL_FAILURE` function should be used instead of the `EXPECT_DEATH` gTest macro.
271+
The `EXPECT_DEATH` gTest macro forks the process which slows down the test execution (especially with the ThreadSanitizer enabled)
272+
and causes issues with running thread. The `IOX_EXPECT_FATAL_FAILURE` registers a temporary error handler and runs the provided
273+
function in a separate thread. When the error handler is called `longjmp` is used to prevent the termination and instead ensures
274+
to gracefully shutdown the thread.
275+
276+
```cpp
277+
#include "iceoryx_hoofs/testing/fatal_failure.hpp"
278+
TEST(MyTest, valueOnNulloptIsFatal) {
279+
iox::optional<bool> sut;
280+
IOX_EXPECT_FATAL_FAILURE<iox::HoofsError>([&] { sut.value(); }, iox::HoofsError::EXPECTS_ENSURES_FAILED);
281+
}
282+
```
283+
267284
## Open points
268285

269286
### Centralized error handling

iceoryx_hoofs/testing/include/iceoryx_hoofs/testing/fatal_failure.hpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ bool FATAL_FAILURE_TEST(const std::function<void()>& testFunction,
8484

8585
/// @brief This function is used in cases a fatal failure is expected. The function only works in combination with the
8686
/// iceoryx error handler.
87+
/// @code
88+
/// TEST(MyTest, valueOnNulloptIsFatal) {
89+
/// iox::optional<bool> sut;
90+
/// IOX_EXPECT_FATAL_FAILURE<iox::HoofsError>([&] { sut.value(); }, iox::HoofsError::EXPECTS_ENSURES_FAILED));
91+
/// }
92+
/// @endcode
8793
/// @tparam[in] ErrorType The error type which is expected, e.g. 'iox::HoofsError'
8894
/// @param[in] testFunction This function will be executed as SUT and is not expected to call the error handler
8995
/// @param[in] expectedError The error value which triggered the fatal failure
@@ -102,6 +108,12 @@ bool IOX_EXPECT_FATAL_FAILURE(const std::function<void()>& testFunction, const E
102108

103109
/// @brief This function is used in cases no fatal failure is expected but could potentially occur. The function only
104110
/// works in combination with the iceoryx error handler.
111+
/// @code
112+
/// TEST(MyTest, valueIsNotFatal) {
113+
/// iox::optional<bool> sut{false};
114+
/// IOX_EXPECT_NO_FATAL_FAILURE<iox::HoofsError>([&] { sut.value(); });
115+
/// }
116+
/// @endcode
105117
/// @tparam[in] ErrorType The error type which is expected if the test fails, e.g. 'iox::HoofsError'
106118
/// @param[in] testFunction This function will be executed as SUT and is not expected to call the error handler
107119
/// @return true if no fatal failure occurs, false otherwise
@@ -111,8 +123,8 @@ bool IOX_EXPECT_NO_FATAL_FAILURE(const std::function<void()>& testFunction)
111123
return !detail::FATAL_FAILURE_TEST<ErrorType>(
112124
testFunction,
113125
[&](const auto error, const auto errorLevel) {
114-
GTEST_FAIL() << "Expected no fatal failure but execution failed! Error code: " << error
115-
<< "; Error level: " << errorLevel;
126+
GTEST_FAIL() << "Expected no fatal failure but execution failed! Error code: "
127+
<< static_cast<uint64_t>(error) << "; Error level: " << static_cast<uint64_t>(errorLevel);
116128
},
117129
[&] {});
118130
return false;

0 commit comments

Comments
 (0)