[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