Skip to content

[idea] An emergency stop of SOEnv on an exception in noexcept context #62

Description

@eao197

There are several noexcept contexts where exceptions are prohibited. For example: on_enter/on_exit handlers for states, not_empty_notificator for mchains. But actions that can throw are often used in such contexts, for example:

st_free.on_enter( [this]() noexcept {
   so_5::send<msg_check_new_load>(*this);
});

A call to so_5::send may throw. If such an exception won't be intercepted, the whole application will crash (due to std::terminate call).

For some types of applications it's a normal behavior. But not always. For example, it's not good to crash a complex GUI application if one so_5::send fails. But it's also not good to just ignore such a problem by using something like that:

st_free.on_enter( [this]() noexcept {
   try {
      so_5::send<msg_check_new_load>(*this);
   } catch(...) {} // Discard the exception.
});

Maybe the better way is to stop the SObjectizer Environment. Something like:

st_free.on_enter( [this]() noexcept {
   try {
      so_5::send<msg_check_new_load>(*this);
   } catch(...) {
      so_environment().stop();
   }
});

But there are some open questions:


Is it always possible to call so_environment_t::stop()? Especially when it's called from state's on_enter/on_exit handlers.

The source code of SObjectizer has to be examined.


It's better to have some helper function that takes a lambda than can throw and wraps it into a noexcept function object that catches exceptions and calls so_environment_t::stop(). Something like:

st_free.on_enter( so_environment().make_stopper_on_exception(
   [this]() {
      so_5::send<msg_check_new_load>(*this);
   } ) );

Or something like (an additional form of on_enter/on_exit method):

st_free.on_enter( so_5::stop_env_on_exception,
   [this]() {
      so_5::send<msg_check_new_load>(*this);
   } ) );

It will be good to store and then access somehow the reason for the environment's shutdown.

Unfortunately, I have no idea what it can look like. But, obviously, such a feature has to be noexcept (so we can't store std::string or another type that can allocate, maybe an object with std::array<char, N> inside, where N will be reasonably long).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions