[IGSTK-Users] Error handling in igstk applications

Torleif Sandnes Torleif.Sandnes at sintef.no
Tue Jun 26 10:11:03 EDT 2007


Thanks Ziv, this seems to be a good solution to my problem.

In addition to funneling the events to a single state, I will have to  
add lines like the following:

"igstkcomponent->AddObserver(theEvent, myErrorObserver);"

for each event I want to handle, right?

Regards,
Torleif

> Hi Torleif,
>
> You can have all these events transition to a single error state  
> and provide the user with an appropriate error message using a map  
> between event and message. Attached is a class that uses this  
> approach. Note that it does not follow the igstk state machine  
> approach but is an example of how to use a map to get the  
> functionality you want.
>
>             hope this helps
>                    Ziv
>
> Torleif Sandnes wrote:
>> Hi.
>> I am building an application that has to read Dicom images and  
>> want to listen for all error events that the imagereader can send.  
>> Based on the error, I want to provide a message to the user  
>> describing the error.
>> Using igstkEventTransductionMacro, I could add a state to my  
>> imagereader component for every errorevent from  
>> igstk::DicomImageReader:
>>    DICOMInvalidRequestErrorEvent
>>    DICOMImageDirectoryEmptyErrorEvent
>>    DICOMImageDirectoryDoesNotExistErrorEvent
>>    DICOMImageDirectoryIsNotDirectoryErrorEvent
>>    DICOMImageDirectoryDoesNotHaveEnoughFilesErrorEvent
>>    DICOMImageSeriesFileNamesGeneratingErrorEvent
>>    DICOMImageReadingErrorEvent
>> This would introduce seven new states and (at least) seven new  
>> transitions. All I want to do with these events is to convert it  
>> into a message to the user, so each transition's processing method  
>> would do essentially the same thing. This seems to be adding a lot  
>> of complexity to my statemachine to accomplish just a little.
>> Ideally, I would like to add only one "imagereading failed" state  
>> to my component and be able to differentiate between the events.  
>> Is this possible?
>> Regards,
>> Torleif Sandnes
>> Sintef Health Research
>> _______________________________________________
>> IGSTK-Users mailing list
>> IGSTK-Users at public.kitware.com
>> http://public.kitware.com/cgi-bin/mailman/listinfo/igstk-users
>
>
> -- 
> Ziv Yaniv, PhD., Research Assistant Professor
> Imaging Science and Information Systems (ISIS) Center
> Department of Radiology
> Georgetown University Medical Center
> 2115 Wisconsin Avenue, Suite 603
> Washington, DC, 20007,
>
> Phone: +1-202-687-7286
> Fax: +1-202-784-3479
> email: zivy at isis.imac.georgetown.edu
> web: http://isiswiki.georgetown.edu/zivy/
> #ifndef _IGSTK_ERROR_OBSERVER_H_
> #define _IGSTK_ERROR_OBSERVER_H_
>
> / 
> ********************************************************************** 
> ****
> * Copyright (c) 2007
> * Computer Aided Interventions and Medical Robotics (CAIMR) group,
> * Imaging Science and Information Systems (ISIS) research center,
> * Georgetown University.
> *
> * All rights reserved.
> *
> * Permission to use, copy, modify, distribute, and sell this software
> * and its documentation for any purpose is hereby granted without fee,
> * provided that:
> * (1) Redistributions of source code must retain the above  
> copyright notice,
> *     this list of conditions and the following disclaimer.
> * (2) Redistributions in binary form must reproduce the above  
> copyright notice,
> *     this list of conditions and the following disclaimer in the  
> documentation
> *      and/or other materials provided with the distribution.
> * (3) The author's name may not be used to endorse or promote  
> products derived
> *     from this software without specific prior written permission.
> * (4) Modified source versions must be plainly marked as such, and  
> must not be
> *     misrepresented as being the original software.
> *
> * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND  
> ANY EXPRESS
> * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED  
> WARRANTIES
> * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  
> DISCLAIMED.
> * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,  
> INCIDENTAL,
> * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT  
> LIMITED TO,
> * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  
> OR PROFITS;
> * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  
> LIABILITY,
> * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING  
> NEGLIGENCE OR
> * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
> EVEN IF ADVISED
> * OF THE POSSIBILITY OF SUCH DAMAGE.
> ********************************************************************** 
> ****/
>
> #include <itkCommand.h>
> #include <itkSmartPointer.h>
> #include <igstkMacros.h>
>
> /**
>  * This class serves a similar function as the errno variable and  
> perror error printing function.
>  * It is an adaptor between the IGSTK event driven error reporting  
> and exception throwing as
>  * used in standard C++.
>  *
>  * After each call to RequestXXX() on a IGSTK component the user  
> should check if an error occured,
>  * using the observer's boolean Error() method, get the associated  
> error message using the observer's
>  * GetErrorMessage() method, and then clear the error using the  
> ClearError() method.
>  *
>  * @author Ziv Yaniv
>  *
>  */
> class IGSTKErrorObserver : public itk::Command
> {
> public:
>   typedef IGSTKErrorObserver               Self;
>   typedef ::itk::Command                   Superclass;
>   typedef ::itk::SmartPointer<Self>        Pointer;
>   typedef ::itk::SmartPointer<const Self>  ConstPointer;
>
>   igstkNewMacro(Self)
>   igstkTypeMacro(IGSTKErrorObserver, itk::Command)
>
>   /**
>    * When an error occurs in an IGSTK component it will invoke this  
> method with the appropriate
>    * error event object as a parameter.
>    */
>   virtual void Execute(itk::Object *caller, const itk::EventObject  
> & event) throw (std::exception);
>   /**
>    * When an error occurs in an IGSTK component it will invoke this  
> method with the appropriate
>    * error event object as a parameter.
>    */
>   virtual void Execute(const itk::Object *caller, const  
> itk::EventObject & event) throw (std::exception);
>   /**
>    * Clear the current error.
>    */
>   void ClearError() {this->errorOccured = false; this- 
> >errorMessage.clear();}
>   /**
>    * If an error occurs in one of the observed IGSTK components  
> this method will return true.
>    */
>   bool Error() {return this->errorOccured;}
>   /**
>    * Get the error message associated with the last IGSTK error.
>    */
>   void GetErrorMessage(std::string &errorMessage) {errorMessage =  
> this->errorMessage;}
>
> protected:
>
>   /**
>    * Construct an error observer for all the possible errors that  
> occur in IGSTK components
>    * used in the DataAcqusition class.
>    */
>   IGSTKErrorObserver();
>   virtual ~IGSTKErrorObserver(){}
> private:
>   bool errorOccured;
>   std::string errorMessage;
>   std::map<std::string,std::string> errorEvent2ErrorMessage;
>
>                //purposely not implemented
>   IGSTKErrorObserver(const Self&);
>   void operator=(const Self&);
> };
>
> #endif //_IGSTK_ERROR_OBSERVER_H_
> #include "IGSTKErrorObserver.h"
> #include <igstkTracker.h>
> #include <igstkEvents.h>
>
> IGSTKErrorObserver::IGSTKErrorObserver() : errorOccured(false)
> {                              //serial communication errors
>   this->errorEvent2ErrorMessage.insert 
> (std::pair<std::string,std::string>(igstk::OpenPortErrorEvent 
> ().GetEventName(),"Error opening com port."));
>   this->errorEvent2ErrorMessage.insert 
> (std::pair<std::string,std::string>(igstk::ClosePortErrorEvent 
> ().GetEventName(),"Error closing com port."));
>                               //tracker errors
>   this->errorEvent2ErrorMessage.insert 
> (std::pair<std::string,std::string>(igstk::TrackerOpenErrorEvent 
> ().GetEventName(),"Error opening tracker communication."));
>   this->errorEvent2ErrorMessage.insert 
> (std::pair<std::string,std::string> 
> (igstk::TrackerInitializeErrorEvent().GetEventName(),"Error  
> initializing tracker."));
>   this->errorEvent2ErrorMessage.insert 
> (std::pair<std::string,std::string> 
> (igstk::TrackerStartTrackingErrorEvent().GetEventName(),"Error  
> starting tracking."));
>   this->errorEvent2ErrorMessage.insert 
> (std::pair<std::string,std::string> 
> (igstk::TrackerStopTrackingErrorEvent().GetEventName(),"Error  
> stopping tracking."));
>   this->errorEvent2ErrorMessage.insert 
> (std::pair<std::string,std::string> 
> (igstk::TrackerUpdateStatusErrorEvent().GetEventName(),"Error  
> getting data from tracker."));
>   this->errorEvent2ErrorMessage.insert 
> (std::pair<std::string,std::string>(igstk::TrackerCloseErrorEvent 
> ().GetEventName(),"Error closing tracker communication."));
>   this->errorEvent2ErrorMessage.insert 
> (std::pair<std::string,std::string> 
> ((igstk::TrackerUpdateStatusErrorEvent()).GetEventName(),"Error  
> updating transformations from tracker."));
> }
> / 
> ********************************************************************** 
> *******/
> void IGSTKErrorObserver::Execute(itk::Object *caller, const  
> itk::EventObject & event) throw (std::exception)
> {
>   std::map<std::string,std::string>::iterator it;
>   std::string className = event.GetEventName();
>   it = this->errorEvent2ErrorMessage.find(className);
>                //listening to an event that wasn't entered into the  
> map of events we listen to
>   if(it == this->errorEvent2ErrorMessage.end()) {
>     std::string logicalErrorMessage = std::string("ErrorObserver:  
> listening to an event (") + className + std::string(") which is not  
> one of the expected events.");
>     throw std::exception(logicalErrorMessage.c_str());
>   }
>   this->errorOccured = true;
>   this->errorMessage = (*it).second;
> }
> / 
> ********************************************************************** 
> *******/
> void IGSTKErrorObserver::Execute(const itk::Object *caller, const  
> itk::EventObject & event) throw (std::exception)
> {
>   const itk::Object * constCaller = caller;
>   this->Execute(constCaller, event);
> }




More information about the IGSTK-Users mailing list