The state machine back-end in backmp11 currently uses the same mechanism as in back for exception handling.
Current behavior
Exception handling turned on (default)
A try-catch block catches a std::exception and forwards it to a callback void exception_caught(event, fsm, exception), and the process_event call returns HANDLED_FALSE.
The return value HANDLED_FALSE is misleading, since the exception throws while the event is being processed. Most likely while it is being handled. Also it's not clear whether the arguments event and fsm are sufficient to handle the exception.
It is generally difficult to really handle an exception at this high level. Exceptions in a state machine are most likely thrown from user code, which users can provide through guards and actions. Guards should naturally be const noexcept, which leaves actions to be the most probable candidates to throw exceptions. The throwing action cannot be identified in the exception_caught(...) callback, and handling an exception is more easily doable with a try-catch block directly within the action.
Exception handling turned off
The try-catch block can be turned off by declaring no_exception_thrown in the front-end.
In this case the user has to be aware that the state machine offers no exception guarantee. If an exception is thrown with exception handling turned off, the machine will be left in an invalid state due to the machine state being stuck in processing.
Proposed behavior
Propagate all exceptions and provide a basic exception guarantee
Provide a basic exception guarantee by ensuring that the machine state always gets reset to idle after processing. A pattern similar to a lock guard should suffice for this.
This way the state machine can remain in a valid state and propagate all exceptions to the caller. The user can decide if and how to handle these exceptions.
The try-catch block with the call to exception_caught(...) as well as the different handling based on no_exception_thrown is then no longer needed and can be removed.
The state machine back-end in
backmp11currently uses the same mechanism as inbackfor exception handling.Current behavior
Exception handling turned on (default)
A try-catch block catches a
std::exceptionand forwards it to a callbackvoid exception_caught(event, fsm, exception), and theprocess_eventcall returnsHANDLED_FALSE.The return value
HANDLED_FALSEis misleading, since the exception throws while the event is being processed. Most likely while it is being handled. Also it's not clear whether the argumentseventandfsmare sufficient to handle the exception.It is generally difficult to really handle an exception at this high level. Exceptions in a state machine are most likely thrown from user code, which users can provide through guards and actions. Guards should naturally be const noexcept, which leaves actions to be the most probable candidates to throw exceptions. The throwing action cannot be identified in the
exception_caught(...)callback, and handling an exception is more easily doable with a try-catch block directly within the action.Exception handling turned off
The try-catch block can be turned off by declaring
no_exception_thrownin the front-end.In this case the user has to be aware that the state machine offers no exception guarantee. If an exception is thrown with exception handling turned off, the machine will be left in an invalid state due to the machine state being stuck in
processing.Proposed behavior
Propagate all exceptions and provide a basic exception guarantee
Provide a basic exception guarantee by ensuring that the machine state always gets reset to
idleafter processing. A pattern similar to a lock guard should suffice for this.This way the state machine can remain in a valid state and propagate all exceptions to the caller. The user can decide if and how to handle these exceptions.
The try-catch block with the call to
exception_caught(...)as well as the different handling based onno_exception_thrownis then no longer needed and can be removed.