iceoryx
iceoryx copied to clipboard
ErrorHandling concept with user defined actions
Brief feature description
In a safety certified environment the user may would like to define what reaction certain errors cause. Like:
- call to
std::terminate - throw an exception
- inform some watch dog and go into a spinlock
Furthermore, to avoid death tests in unit tests customizing the behavior so that exceptions can be thrown can be useful. This would require to get rid of noexcept. The idea would be that iceoryx never throws an exceptions but allows the user to overload/define the error handling so that it is capable of throwing custom exception which is at the moment impossible since noexcept is in place.
Details
Iceoryx as a framework should enable the user to pursue any error concept they like with a fitting interface. This error concept should then be used uniformly in all iceoryx components so that we have one single call like errorHandler( instead of a wild mixture of std::terminate, cxx::Expects, cxx::Ensures, assert etc.
This call may require the origin, cause, severity of the error so that user defined callbacks can be defined to react differently based on origin, severity and cause.
@elBoberido fell asleep on his keyboard and maybe the products of his dreams can provide us with further insights, see here
Definition of done
The error handling concept is documented in: doc/design/error-handling.md. For this the current error handling concept may have to be discarded/rewritten.
Follow-up issues can then implement the error concept.
Further insights
We have the ability to allow the user to throw exceptions in callbacks, cxx::function or cxx::function_ref but noexcept will cause always a std::terminate.
This is especially a problem in tests where we avoid fatal errors with Expects or the error handler. This is untestable since the errorhandler calls the custom handler and then continues - we require an exception here to make the code testable.
Think of testing this piece of code:
void doStuff(someClass * ptr) {
iox::cxx::Expects(ptr != nullptr);
ptr->doStuff();
}
A test like
auto handle =
iox::ErrorHandler::setTemporaryErrorHandler([&](auto, auto, auto) { wasErrorHandlerCalled = true; });
doStuff(nullptr);
EXPECT_TRUE(wasErrorHandlerCalled);
will always end up with a segfault since the code in doStuff continues after the error handler call. But if we would allow exceptions we could throw an exception in the error handler and safely return to the test.
Then the test only has to verify that the exception was thrown and this indicates that we correctly used the error handler in doStuff.
Requirements
Open for discussions
- exchange error handling on compile time, switch on runtime is forbidden
- must be defined via
iceoryx_platformand stored in platform
- must be defined via
- no dependencies to
iceoryx_hoofs - it should support exceptions, the whole iceoryx code base should support exceptions (remove noexcept)
- 3 error levels, moderate, error and fatal
- on fatal the error handler must be blocking
Todo
- [ ] Replace all
assertwith the new one - [ ] Taken from #1196 : remove
requires.hppand replaceExpectsandEnsurewithIOX_ASSERT
@elfenpiff Thanks for creating this error! I checked the SEI CERT C++ rule-set mentioned in the CONTRIBUTING.md: It's quite plausible that terminating the program abruptly without calling the d'tor may cause security issues e.g. left-over open sockets. See rule ERR50-CPP.
Working on this now. Starting with a list of requirements followed by a prototype. Will be based on similar principles as the logger to allow defining it on a platform basis.