
template <class FSM,class Event> void exception_caught (Event const&,FSM& fsm,std::exception& ) { fsm.process_event(ErrorConnection()); }
In a telecom application we are doing something similar, but we have several submachines, and we can have exceptions during the processing of the error event. In each submachnie we throw the exception further to the container machine. // Base template class for submachines template <typename T> class BaseStateMachine: public msm::front::state_machine_def<T> { public: // ... // Exception Handling template <class FSM,class Event> void exception_caught (Event const&,FSM& fsm,std::exception& e) { _DEBUG_LIB(&fsm.getLogger()," exception_caught "); boost::exception* be = dynamic_cast<boost::exception*>(&e); if(be){ *be << EMsmEvent(removeNamespace<Event>()); throw; } else{ BOOST_THROW_EXCEPTION(MsmException() << EMsmEvent(removeNamespace<Event>())); } throw; } // ... }; In the outermost machine we have: // Base template class for the outermost machines template <typename T> class BaseOutermostStateMachine: public BaseStateMachine<T> { public: // Exception Handling template <class FSM,class Event> void exception_caught (Event const& event,FSM& fsm,std::exception& e) { _WARNING_LIB(&fsm.getLogger()," Error during state machine event processing "); _INFO_LIB(&fsm.getLogger(),boost::diagnostic_information(e)); _DEBUG_LIB(&fsm.getLogger()," processing event EvError "); fsm.process_event(EvError()); } template <class FSM> // error during error handling void exception_caught (EvError const& event, FSM& fsm, std::exception& e) { _INFO_LIB(&fsm.getLogger()," exception_caught during processing EvError"); // Propagate the exception out from the fsm. The fsm will be terminated. BaseStateMachine<T>::exception_caught(event, fsm, e); } }; When there is an error in the outermost statemachine we propagate the exception out from it. At this point, the client code (which calls the process_event function) shall restart the state machine therefore resetting it to the initial state. But we cannot simply restart the machine because after we have thrown the exception out from it, it becomes nonresponsive, i.e. it does not react to the fsm->stop() and fsm->start() sequence. So we came up with the following: void Client::reCreateBackEnd() { if(backEnd){ // backEnd is a smart pointer backEnd->stop(); backEnd.reset(); } // Constructing the BackEnd backEnd.reset(new ...); backEnd->set_states( ... ); backEnd->start(); } It is too drastic to recreate the back end, I think. Christophe, is there any more elegant solution to do this? Why is it that the state machine becomes not restartable if an exception is thrown out from it? BR, Gabor