I have implemented a state machine that inherits boost::statechart. When I call fsm.process_event( some_event() )
which reaction is expected to throw exception it turns out that after I handle the exception with try-catch block my statemachine instance fsm
is terminated. That is, fsm.terminated()
returns true
. In some cases I don't want it to get terminated. Like when I want the statemachine to throw exception to inform the caller of fsm.process_event( irrelevant_event() )
for non-handled event and to keep its current prior to the event state.
In short - how can I prevent boost::statechart
from terminating after it throws an exception and keep its prior to the exception state?
Example Code:
namespace sc = boost::statechart;
class State;
struct some_event : public sc::event<some_event> { };
class FSM
: public sc::state_machine< FSM, State, std::allocator<void>, sc::exception_translator<> >
{
public:
FSM()
{
cout<<"FSM::FSM()"<<endl;
}
virtual ~FSM()
{
cout<<"FSM::~FSM()"<<endl;
}
};
class State : public sc::simple_state< State, FSM >
{
public:
State()
{
cout<<"State::State()"<<endl;
}
virtual ~State()
{
cout<<"State::~State()"<<endl;
}
typedef boost::mpl::list<
sc::custom_reaction< some_event >,
sc::custom_reaction< sc::exception_thrown >
> reactions;
sc::result react( const some_event & e)
{
cout<<"State::react( const some_event &)"<<endl;
throw std::exception();
return this->discard_event();
}
sc::result react( const sc::exception_thrown & e)
{
cout<<"State::react( const sc::exception_thrown &)"<<endl;
throw;
return this->discard_event();
}
};
int main()
{
FSM fsm;
fsm.initiate();
try
{
fsm.process_event(some_event());
}
catch(...)
{
cout<<"Exception caught"<<endl;
}
if(fsm.terminated())
{
cout<<"fsm2 is TERMINATED"<<endl;
}
else
{
cout<<"fsm2 is RUNNING"<<endl;
}
return 0;
}
Code Output:
FSM::FSM()
State::State()
State::react( const some_event &)
State::react( const sc::exception_thrown &)
State::~State()
Exception caught
fsm2 is TERMINATED
I want it to Output:
FSM::FSM()
State::State()
State::react( const some_event &)
State::react( const sc::exception_thrown &)
State::~State()
Exception caught
fsm2 is RUNNING