[IGSTK-Users] Error handling in igstk applications

Ziv Yaniv zivy at isis.imac.georgetown.edu
Tue Jun 26 09:50:22 EDT 2007


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/
-------------- next part --------------
#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_
-------------- next part --------------
#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