Skip to content

backmp11: Ensure basic exception guarantee and propagate exceptions to the caller #221

@chandryan

Description

@chandryan

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.

Metadata

Metadata

Assignees

No one assigned

    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