Helloe Joe :-) [sorry, couldn't resist] On Mon, 4 Feb 2002 9:30:57 -0500 joer00@bellsouth.net wrote concerning "[ROOT] getting the last error": > Hi Rooters, > > I posted this before and got the impression that I just cant check > for errors, but Anton Fokin told me it shouls be possible via > SetErrorHandler(). But HOW ?? There is no documentaion in the root > docs, none in the class index and serach the root page did not > return any result. If you bothered to look for the implmentation of SetErrorHandler, which is easy using the LXR interface at the ROOT web-site, then you'd have found it straight of - that's what I just did. And I assume reading some 30 lines of code is not something that bothers you, seeing that you're developing stuff yourself :-) > So all I need is to NOT print errors in the console window (if i set > ignore levele to 5000, the default error handler just aborts !) and > GET the last occured error to decide what my programm is > doing. Something simple like: > > SomeClass.SomeMethod("This might set an Error"); > if(gError) > { > QMessageBox::warning(this,"test",gErrorMessage); > DoSomething; > } See the declaration file base/inc/TError.h, and the corresponding implementation file base/src/TError.cxx. In base/inc/TError.h the type ErrorHandlerFunc_t is defined as a pointer to a funtion, like typedef void (*ErrorHandlerFunc_t)(int level, Bool_t abort, const char *location, const char *msg); which is the type that SetErrorHandler expects. Hence, you can not have a member function of a class directly as a error handler but, your error handler function can be a wrapper that uses a static/global pointer to an object of some class: void MyErrorHandler(int lvl, Bool abt, const char* loc, const char* msg) { // Get a pointer to the current error handler class MyErrorClass* errorObject = MyErrorClass::Instance(); if (errorObject) // Use it if it exists errorObject->ErrorHandler(lvl, abt, loc, msg); else // Fall-back to normal ROOT error handler DefaultErrorHandler(lvl, abt, loc, msg); } class MyErrorClass { protected: ostream* fStream; static MyErrorClass* fgInstance; public: MyErrorClass() { fStream = &cerr; } static MyErrorClass Instance() { return fgInstance; } virtual void ErrorHandler(int lvl, Bool abt, const char* loc, const char* msg) = 0; virtual void SetStream(const ostream& stream=cerr) { fStream = &stream; } }; static MyErrorClass* MyErrorClass::fgInstance; class QtErrorClass : public MyErrorClass { public: QtErrorClass() { fStream = 0; fgInstance = this; } virtual ~QtErrorClass() { fgInstance = 0; } virtual void ErrorHandler(int lvl, Bool abt, const char* loc, const char* msg) { TString errMessage(msg); TString errTitle; if (level >= kInfo) errTitle = "Info"; if (level >= kWarning) errTitle = "Warning"; if (level >= kError) errTitle = "Error"; if (level >= kSysError) errTitle = "SysError"; if (level >= kFatal) errTitle = "Fatal"; if (loc && loc[0] != '\0') { errTitle += " in <"; errTitle += loc; errTitle += ">"; } if (abt) errorMessage += "\nAborting!"; QMessageBox::warning(this, errTitle.Data(), errorMessage.Data()); if (abt) ::abort(); } } I prefer static members to global variables, though they are almost the same thing, since it looks more OO, and it's easier to make reentrant (thread safe) code that way. You can then enable the use of MyErrorHandler with Init() { SetErrorHandler(MyErrorHandler); // and use the Qt one new QtErrorClass; } int main(int argc, char** argv) { Init(); ... } A word of caution: I have not tried this, but in principal is should work. You may need to specify "C" linkage for MyErrorHandler, but I don't think so. Yours, Christian Holm Christensen ------------------------------------------- Address: Sankt Hansgade 23, 1. th. Phone: (+45) 35 35 96 91 DK-2200 Copenhagen N Cell: (+45) 28 82 16 23 Denmark Office: (+45) 353 25 305 Email: cholm@nbi.dk Web: www.nbi.dk/~cholm
This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:50:41 MET