/****************************************************************************/ /* */ /* How to create Zoom Exception classes */ /* */ /****************************************************************************/ Summary: This short guide describe how to implement simple Zoom Exception classes. For example purpose, we will implement the following exception classes tree: ZMxTop, the top most exception, ZMxHepTuple and ZMxHistogram, that directly inherit from ZMxTop, and HepTuple::ZMxColumn, that inherit from ZMxHepTuple. Each of the exception classes have a static interface and a dynamic interface. The static interface contain method like setHandler, setLogger that let you access and modify information that is common to all the exception of one particular class. The dynamic interface, described in the ZMexception class, let you access and modify information for each particular instance of the exception class. Simple implementation: The ZMexception.h header file provide a few preprocessor macro that let you define simple class. For example the following defines ZMxTop, ZMxHepTuple and ZMxHistogram ZMxTopDefinition(ZMxTop) ZMxCompleteDefinition(ZMxTop,ZMxHepTuple) ZMxCompleteDefinition(ZMxTop,ZMxHistogram) In addition to this definition that belong in a header file, you need to instantiate the static member of each class in a .cc file; for example: ZMexceptInfo ZMxTop::information("ZMxTop","Top Exception"); ZMexceptInfo ZMxHepTuple::information("ZMxHepTuple", "HepTuple"); ZMexceptInfo ZMxHistogram::information("ZMxHistogram", "Histogram"); Complex implementation: If you want to offer more that the core interface for you exception, you can also customize it using more detailed macro; For example: class ZMxColumn : public ZMxHepTuple { public: static ZMexceptInfo information; ZMexceptionWrappers; virtual ZMexception* copy () { return new ZMxColumn(*this); }; ZMxColumn(string msg,string ColumnName, ZMxSeverityLevel level = EndOfSeverity) : ZMxHepTuple(msg,level),_name(ColumnName) { init (level);}; virtual string message() { return ZMxHepTuple::message() + "At column: " + _name; }; private: string _name; }; The Macros: ZMxTopDefinition(Class) Expand to the definition of an exception class named Class. This class is intended to be the top most exception class in your hiearchy. It only inherit its interface from ZMexception. ZMxCompleteDefinition(Parent,Class) Expand to the definition of an exception class named Class that inherit from the class named Parent. It provide all the necessary methods and data members for an exception class. The parent Class is assumed to be a simple exception class which have a constructor with the signature Parent(string msg,ZMxSeverityLevel level); ZMxContentDefinition(Parent,Class) Expand to the definition of all data member and method needed by a simple exception class named Class and inherit from Parent. It contains: a simple constructor that takes a string, and a ZMxSeverityLevel, a method named copy() that returns a copy of the current instance, the information data member and the need accessor methods ZMexceptionWrappers This macro is used by all the above macro to expand to the method needs by all exception class (except for the constructor and the copy() method). It defines: static void setHandler(const ZMhandler& newHandler); // Replace previous handler and put it on a 1 element deep stack static void restorePreviousHandler(); static void pushHandler(const ZMhandler& newHandler) ; // Replace previous handler and put it on a infinite stack static void popHandler(); static const ZMhandler& handler(); // return the current handler. static void setLogger(const ZMlogger& newLogger); // Replace previous logger and put it on a 1 element deep stack static void restorePreviousLogger(); static void pushLogger(const ZMlogger& newLogger); // Replace previous logger and put it on a infinite stack static void popLogger(); static const ZMlogger& logger(); // return the current logger. virtual string preamble() const; virtual ZMxAction handle(); virtual bool log(); virtual void init(); The data member: Each class need to have a static data member named information of the type ZMexceptInfo. This data member need to be instanciated for each class. Its constructor signature is: ZMexceptInfo(int id, string preamble, ZMxSeverityLevel s = Error, ZMlogger* l = NULL, ZMhandler* h = NULL); id: the identification string for the exception class It should be the same as the name of the exception Class preamble: the string that will prelude all the error message printed by instance of this class. s: the default severity level of the instance of this class. This can be over-ridden at construction time for each instance. l: the logger used to print all the error message of this class. If it is NULL, it will use the logger of the parent class h: a handler for the exceptions of this class. If left NULL, they will handled by the handler of the parent class. If no handler have been set for any exception class, the exception will actually be thrown Things that may be added later: default depth of the push/pop stack for handler and/or logger.