I’d like to have a possibility to break the execution of an interpreted script if some subrutine (compiled or interpreted) encounters an error and further execution of the script makes no sens. In compiled code I’d use exception handling, however this doesn’t still work in cint reliably (catching std::exception thrown in compiled code crashes root session).
What is the proper usage of TObject::Error() and Fatal()? Is there a setting so that calling TObject::Error() breaks the script execution and returns to cint prompt?
Thanks a lot.
Root 5.20_msvc8.0_debug on winxp_sp2
I’m sending a minimal example to reproduce my problem with exception handling using TEveException.
To reproduce run in cint:
root  .L except_class.cpp+
root  .x except_script.cpp
SomeClass constructor called
calling throw exception
Exception: Exception from SomeClass::Second - b is a null-dim vector
— crash of root.exe (cint)
The some behavior using my TNException class, defined in except_class.h (uncomment).
Running Windows XP sp2, MC VisualC++ Express (8.0),
Root 5.20 binary with debug info (for VS8.0)
Thanks a lot for analyzing the problem. My next question is what is the purpose of TObject::Error and TObject::Fatal. This functions seem to me quite unusefull - only printing a message.
However, if TObject::Fatal forced the runtime/cint to abort execution of the running command leaving the global object in the root environment (not crashing cint), I could avoid the exception handling in most cases - I’d use the thrown exception anyhow just to report the error without catching statement.
[For context. please remember that ROOT was developed before any compiler even started to (properly) implement exception (handling)].
Fatal should be used in the case where an error that can not possibly be recovered from has occurred (i.e. clearly halting where the error happened rather than in some other remotely related place in the code).
Error should be used to indicate to the user than an Error has occurred but the program might be able to go on, possibly with result that are different from what is expected. A function that is issuing an Error usually also returns an Error code so that the caller can detect the issue.
Finally I’ve found a “good enough” solution to stop further execution of a script if an error ocured somewhere in the compiled/interpreted code and further execution of the script could be dangerous (crashes cint or so) without exception handling.
I define folloving static methods, where the DefaultErrorHandler is extended, so a global variable is set.
void MyErrorHandler(Int_t level, Bool_t abort_bool, const char *location, const char *msg)
SomeClass::fgError = true;
DefaultErrorHandler( level, abort_bool, location, msg);
cout << "Error ocured that requires abort of script" << endl;
fgError = false;
In the main script I periodically check by calling
if(SomeClass::IsError()) return NULL;
if serious error occured and allows to quit the script.
It woudl be nice to have a standard interface for such “error checking” in the root distribution