Boost logo

Boost Users :

Subject: [Boost-users] [msm] handle errors and no_transition
From: Sam Fisher (infest21h_at_[hidden])
Date: 2014-03-20 03:23:31


  Hi,

I have root fsm which has a sub-fsm. In the sub-fsm there are some
useful actions that can throw exceptions.
For that case any fsm has its own exception handler that translates
exception into a generic error event:

template <typename Event, typename OtherFSM>
void exception_caught(Event&, OtherFSM& fsm, std::exception& e)
{
        fsm.process_event(error());
}

I faced a strange problem: if an exception occurs, the sub successfully
goes to Error state, the root has no_transition
I use boost 1.55 and VS2013

there are transition tables:

Sub:
Error & Finish - exit points
A_Exception action generates exception

typedef ::boost::mpl::vector<Empty, AllOk> initial_state;

struct /*sub*/ transition_table : public ::boost::mpl::vector <
        // Start Event Next Action Guard
        //
+----------------+---------------+------------------+----------------------+--------------------------+
        Row < Empty , none , Waiting , none
                , none >,
        Row < Waiting , process , Process , A_Exception
         , none >,
        Row < Process , none , Finish , none
                , none >,
        //
+----------------+---------------+------------------+----------------------+--------------------------+
        Row < AllOk , error , Error , none
                , none >
        //
+----------------+---------------+------------------+----------------------+--------------------------+
> {};

Root:

struct S
{
        typedef SubFsm::exit_pt<SubFsm_::Error> Error;
        typedef SubFsm::exit_pt<SubFsm_::Finish> Finish;
};

struct /*root*/ transition_table : public ::boost::mpl::vector <
        // Start Event Next Action Guard
        //
+----------------+---------------+------------------+----------------------+--------------------------+
        Row < Empty , init , Initial , none , none
>,
        Row < Initial , sub , SubFsm , none , none
>,
        //
+----------------+---------------+------------------+----------------------+--------------------------+
        Row < S::Error , error , Error , none , none
>,
        Row < S::Finish , none , Initial , none , none
>
        //
+----------------+---------------+------------------+----------------------+--------------------------+
> {};

the control flow:

Root root;
root.start();

root.process_event(init());
root.process_event(sub());
root.process_event(process());

output log:

=============> start

Root_::InitEvent: Enter to Root_ state.
Root_::InitEvent: Enter to Root_::Empty state.

=============> init

Exit from Root_::Empty state.
init: Enter to Root_::Initial state.

=============> sub

Exit from Root_::Initial state.
sub: Enter to Root_::SubFsm_ state.
sub: Enter to SubFsm_::Empty state.
sub: Enter to SubFsm_::AllOk state.
Exit from SubFsm_::Empty state.
front::none: Enter to SubFsm_::Waiting state.

=============> process

Exit from SubFsm_::Waiting state.
SubFsm_::A_Exception()
State machine produces an exception on event process
         Current state: SubFsm_::Waiting
         Message: A_Process exception
Exit from SubFsm_::AllOk state.
error: Enter to SubFsm_::Error state.
No transition from state Root_::SubFsm_ on event process
Exit from SubFsm_::Waiting state.
Exit from SubFsm_::Error state.
Exit from Root_::SubFsm_ state.
error: Enter to Root_::Error state.

A I understood, after exception comes, the "process" event now in kind
of "unhandled" state. So it rises up to the root fsm that doesn't have
any suitable transition

How to make the root or sub to "forget" about unhandled event?


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net