======Error Handler Usage====== The error handler is also a sequence. However, it will be used in case of an exception, so the user knows that it is a recovery pass. To create a new error handler, you have to derive from the class //ErrorHandler// built in the framework. class MyErrorHandlerA : public eeros::sequencer::ErrorHandler Then you can implement the //run()// method, including all the functionality, to either solve the problem causing the exception or restart the system. void MyErrorHandlerA::run(){ Reset(); Referencing(); RestartSequence(); } This //run()// method will be called in the base class //Sequence// of the framework if an exception was thrown. The exception is a //SequenceException// of the framework; it can be thrown at any time. e.g.: throw new eeros::sequencer::SequenceException(this, static_cast(&MySequence::MoveException), static_cast(&MySequence::Initialised), errorHandlerA, false, true, "TestException"); The constructor has following parameters: SequenceException(Sequence* seqCause, Sequence::method cause, Sequence::method next, ErrorHandler* error, bool toBegin, bool goToNext, std::string reason); __Parameter //seqCause// und //cause//:__ The exception occured in the method //cause// of the sequence //seqCause//. __Parameter //next//:__ If //toBegin// is false and //goToNext// true, then this is the next method on which the sequence continues, after error handling has finished! __Parameter //toBegin//:__ Is //toBegin// true and //goToNext// false, so the sequence is restarted. (please refer also to the parameter //next//). Please note: //toBegin// and //goToNext// can not be true in the same exception! __Parameter //error//:__ //error// is the //ErrorHandler//, which defines the behaviour on an exception. __Parameter //goToNext//:__ Is //toBegin// false and //goToNext// true, then the sequence continues at the //next// methode after the error handling. __Parameter reason:__ error message =====Case 1===== {{ .:errorhandlercase1.png?300 | //Exception Flow Case 1//}} exception: throw new eeros::sequencer::SequenceException(this, static_cast(&MySequence::MoveException), 0, errorHandlerA, true, false, "TestException"); =====Case 2===== {{ .:errorhandlercase2.png?300 | //Exception Flow Case 2.1//}} exception: throw new eeros::sequencer::SequenceException(this, static_cast(&MySequence::MoveException), 0, errorHandlerA, false, false, "TestException"); {{ .:errorhandlercase2b.png?300 | //Exception Flow Case 2.2//}} exception: throw new eeros::sequencer::SequenceException(this, static_cast(&MySequence::MoveException), static_cast(&MySequence::Homed), errorHandlerA, false, true, "TestException"); =====Case 3===== {{ .:errorhandlercase3.png?300 | //Exception Flow Case 3//}} exception: throw new eeros::sequencer::SequenceException(this, static_cast&MySequence::MoveException), 0, errorHandlerA, true, false, "TestException"); The //ErrorHandlerA// calls the second error handler //ErrorHandlerB//. MyErrorHandlerB* errorHandlerB = dynamic_cast(eeros::sequencer::ErrorHandler::getErrorHandler("MyErrorHandlerB")); if(!errorHandlerB){ errorHandlerB = new MyErrorHandlerB("MyErrorHandlerB"); } errorHandlerB->run(); =====Case 4===== {{ .:errorhandlercase4.png?300 | //Exception Flow Case 4.1//}} exception: throw new eeros::sequencer::SequenceException(this, static_cast(&MySequence::MoveException), 0, errorHandlerA, false, false, "TestException"); {{ .:errorhandlercase4b.png?300 | //Exception Flow Case 4.2//}} exception: throw new eeros::sequencer::SequenceException(this, static_cast(&MySequence::MoveException), static_cast(&MySequence::Homed), errorHandlerA, false, true, "TestException"); =====Case 5===== {{ .:errorhandlercase5.png?300 | //Exception Flow Case 5//}} exception: throw new eeros::sequencer::SequenceException(this, static_cast(&MySequence::MoveException), 0, errorHandlerA, true, false, "TestException"); In the case, which the sequencer will be restarted on an exception, the sub-sequencer could be kept on running state or it could also be restarted. This can be choosen by the user. The code below shows how you can solve it. MySequencer* subSequencer = dynamic_cast (eeros::sequencer::Sequencer::getMainSequencer()->findSequencer("SubSequencer")); bool seqIsNew = false; if(!subSequencer){ //use pointer to leave the object in memory!! //without pointer the objetct will be destroyed. subSequencer = new MySequencer("SubSequencer"); seqIsNew = true; //callerThread for NonBlocking Sub Sequence is a new Sequencer //please take attention, if this Object looses scope, so it will be deleted!! //that's why you should use a pointer to allocate memory!! //else the pointer in the Executor runnables list of the Sequencer will point to nowhere!! } NonBlockingSubSequence* subSequence = dynamic_cast (eeros::sequencer::Sequence::getSequence("NonBlockingSubSequence")); if(!subSequence){ //MyNonBlockingSubSequence is a Runnable!! subSequence = new NonBlockingSubSequence("NonBlockingSubSequence", *subSequencer); if(seqIsNew){ //now we start the Thread of the subSequencer subSequencer->start(); } } try{ if(!seqIsNew && restartSequencer && subSequencer && subSequencer->getStatus() != eeros::kStopped){ eeros::ExecutorService::waitForSequenceEnd(subSequencer); subSequencer->start(); } }catch(char *str){ } If restartSequencer is true, so the sub-sequencer will be restarted and you have to wait for the termination of the running sub-sequencer. If restartSequencer is false, so the sub-sequencer runs until he finished, without restarting. =====Case 6===== {{ .:errorhandlercase6.png?300 | //Exception Flow Case 6.1//}} exception: throw new eeros::sequencer::SequenceException(this, static_cast(&MySequence::MoveException), 0, errorHandlerA, false, false, "TestException"); {{ .:errorhandlercase6b.png?300 | //Exception Flow Case 6.2//}} exception: throw new eeros::sequencer::SequenceException(this, static_cast(&MySequence::MoveException), static_cast(&MySequence::Homed), errorHandlerA, false, true, "TestException"); =====Case 7===== {{ .:errorhandlercase7.png?300 | //Exception Flow Case 7//}} exception: throw new eeros::sequencer::SequenceException(this, static_cast(&MySequence::MoveException), 0, errorHandlerA, true, false, "TestException"); =====Case 8===== {{ .:errorhandlercase8.png?300 | //Exception Flow Case 8.1//}} exception: throw new eeros::sequencer::SequenceException(this, static_cast(&MySequence::MoveException), 0, errorHandlerA, false, false, "TestException"); {{ .:errorhandlercase8b.png?300 | //Exception Flow Case 8.2//}} exception: throw new eeros::sequencer::SequenceException(this, static_cast(&MySequence::MoveException), static_cast(&MySequence::Homed), errorHandlerA, false, true, "TestException");