#include <syslog.h> // For logging exceptions to log file
#include <errno.h> // list the exception codes
#include <string>
+#include <vector>
#include <exception> // base ancestor stl::exception
namespace exception {
extern pthread_mutex_t METHOD_MUTEX; // used in order to store info into a file (rather then syslog)
-#define GLITE_STACK_TRY(method_name) std::string METHOD = method_name ; try {
-#define GLITE_STACK_CATCH() } catch (glite::wmsutils::exception::Exception &exc){ throw glite::wmsutils::exception::Exception ( __FILE__ , METHOD , &exc) ; }
+#define GLITE_STACK_TRY(method_name) std::string METHOD = method_name ; int LINE = __LINE__ ; try {
+#define GLITE_STACK_CATCH() } catch (glite::wmsutils::exception::Exception &exc){ exc.push_back ( __FILE__ , LINE, METHOD ); throw exc ; }
/**
* The Exception base classe contains attributes into which are placed exception information and provides
*@return the string representation of the stack trace: each line correspond to an exception message
*/
virtual std::string printStackTrace() ;
-
+ /**
+ * Return the list of methods that caused the Exception
+ */
+ virtual std::vector<std::string> getStackTrace() ;
+ /**
+ * Update stack information
+ */
+ virtual void push_back ( const std::string& source, int line_number, const std::string& method ) ;
protected:
Exception();
int error_code;
std::string exception_name;
std::string method_name ;
std::string stack;
+ std::vector< std::string> stack_strings ;
std::string ancestor ;
}; //End Exception Class
}}} // Closing namespace
#include "glite/wmsutils/exception/Exception.h"
#include "glite/wmsutils/exception/exception_codes.h"
-namespace glite {
-namespace wmsutils{
+namespace glite {
+namespace wmsutils{
namespace exception {
using namespace std ;
pthread_mutex_t METHOD_MUTEX ; // This mutex is used in order to lock the file for writing log infornation
/* *********************************
* Exception Class Implementation
************************************/
+//Constructor/Destructor
+
Exception::Exception () {
- stack= "";
line = 0;
} ;
Exception::~Exception() throw(){ }
/**
* Exception chainig
*/
-Exception::Exception ( const string& source,
-const string& method,
-Exception *e){
+void Exception::push_back ( const string& source, int line_number, const string& method ){
+ stack_strings.push_back ( dbgMessage() ) ;
+ ancestor = what() ;
source_file = source ;
+ line = line_number ;
+ method_name = method;
+ error_message = "" ;
+ exception_name="" ;
+}
+Exception::Exception( const std::string& file, int line_number, const std::string& method, int code, const std::string& name)
+ : error_code(code), exception_name(name){
+ source_file = file;
+ line = line_number;
method_name = method;
- error_message = "";
- stack= e->printStackTrace();
- ancestor = e->what() ;
- line = 0;
- error_code= 0;
-};
-Exception::Exception( const std::string& file, int line_number,
- const std::string& method, int code, const std::string& name): error_code(code), exception_name(name){
- source_file = file;
- line = line_number;
- method_name = method;
- stack= "";
};
-Exception::Exception (const string& source,
- const string& method,
- int code,
- const string& exception)
+Exception::Exception (const string& source, const string& method, int code, const string& exception)
: error_code(code), exception_name(exception){
- source_file = source;
- method_name = method;
- stack= "";
- line = 0;
+ source_file = source;
+ method_name = method;
+ // stack= "";
+ line = 0;
};
-
int Exception::getCode(){
- if (error_code != 0) return error_code ;
- else return WMS_COMMON_BASE;
+ if (error_code != 0)
+ return error_code ;
+ else
+ return WMS_COMMON_BASE;
};
-
const char* Exception::what() const throw(){
- if (!ancestor.empty() ) return ancestor.c_str() ;
- if ( error_message != "") return error_message.c_str() ;
- else return "" ;
-};
+ if (!ancestor.empty() )
+ return ancestor.c_str() ;
+ if ( error_message != "")
+ return error_message.c_str() ;
+ else return "" ;
+};
string Exception::getExceptionName(){
- if (exception_name!= "") return exception_name;
- else return "" ;
+ if (exception_name!= "")
+ return exception_name;
+ else
+ return "" ;
};
-void Exception::log(const std::string& logfile){
- if ( logfile == "") syslog ( LOG_PERROR, (char *) (dbgMessage()).c_str() );
- else{
- pthread_mutex_lock( &METHOD_MUTEX); // LOCK
- ofstream fout ((char *) logfile.c_str() , ios::app ); //Open the file for writing (if it doesn't exist then it will be created)
- fout << "\n" << dbgMessage() ; //write (append) the message
- fout.close(); //close the file
- pthread_mutex_unlock( &METHOD_MUTEX); // UNLOCK
- }
+void Exception::log(const std::string& logfile)
+{
+ if ( logfile == "")
+ syslog ( LOG_PERROR, (char *) (dbgMessage()).c_str() );
+ else{
+ pthread_mutex_lock( &METHOD_MUTEX); // LOCK
+ //TBD : test if file exist-->>Create HEADER ??
+ ofstream fout ((char *) logfile.c_str() , ios::app ); //Open the file for writing (if it doesn't exist then it will be created)
+ fout << "\n" << dbgMessage() ; //write (append) the message
+ fout.close(); //close the file
+ pthread_mutex_unlock( &METHOD_MUTEX); // UNLOCK
+ }
};
string Exception::printStackTrace(){
- return stack + "\n" + dbgMessage();
+ string stack = "" ;
+ for (unsigned int i = 0 ; i < stack_strings.size() ; i++ ){
+ stack+=stack_strings[i] +"\n" ;
+ }
+ return stack +dbgMessage();
+};
+vector<string> Exception::getStackTrace(){
+ // make a copy of the stack
+ vector<string> stack = stack_strings ;
+ stack.push_back(dbgMessage() ) ;
+ return stack;
};
string Exception::dbgMessage(){
- string result ;
- //Adding exception Name
- if ( exception_name!="") result = exception_name ;
- //Adding error msg
- if (error_message!="") result +=": " + string(what());
- // Appending newline if needed
- if (result != "") result+="\n";
- //Adding Source
- result +=" at " + source_file ;
- //Adding line number
- if (line!=0){
- char buffer [1024] ;
- sprintf (buffer, "%i" , line) ;
- result += " Line: " + string ( buffer );
- }
- result +=" " ;
- //Adding Method Name
- if (method_name != "") result += "Method: " +method_name ;
- return result;
+ string result ;
+ //Adding exception Name
+ if ( exception_name!="")
+ result = exception_name ;
+ //Adding error msg
+ if (error_message!="")
+ result +=": " + string(what());
+ if (result != "")
+ result+="\n";
+ //Adding Source
+ result +="\tat " + method_name +"[" +source_file;
+ //Adding line number
+ if (line!=0){
+ char buffer [1024] ;
+ sprintf (buffer, "%i" , line) ;
+ result += ":" + string ( buffer );
+ }
+ result +="]" ;
+ return result;
}
}}} // Closing namespace