Exception.cpp

00001 #include "Exception.h"
00002 #include "SctNames.h"
00003 #include "StdExceptionWrapper.h"
00004 #include "CorbaExceptionWrapper.h"
00005 #include <mrs/message.h>
00006 #include <sstream>
00007 #include <cstdlib>
00008 #include <iostream>
00009 
00010 using namespace std;
00011 
00012 namespace Sct {
00013     
00014 AbstractThrowable::AbstractThrowable() throw() {
00015 }
00016     
00017 long AbstractThrowable::sendToMrs(SEVERITY s) throw() {
00018     setSeverity(s);
00019     return sendToMrs();
00020 }
00021 
00022 long AbstractThrowable::sendToMrs() const throw() {
00023     MRSStream& msg = SctNames::Mrs();
00024     msg << id << MRS_TEXT(what());
00025     msg << getSeverity() << ENDM;
00026     return msg.getState();
00027 }
00028 
00029 void AbstractThrowable::setSeverity(SEVERITY s) throw() {
00030     severity = s;
00031 }
00032 
00033 SEVERITY AbstractThrowable::getSeverity() const throw() {
00034     return severity;
00035 }
00036 
00037 const char* AbstractThrowable::what() const throw() {
00038     if (text.length() > 0) return text.c_str();
00039     
00040     ostringstream oss;
00041     oss << "Name: [" << name << "]";
00042     if (file.length() > 0) {
00043       oss << " Created at: [" << file << ":" << line << "]";
00044     } 
00045     oss << endl << getMessage();
00046     if (cause.get()) {
00047       oss << endl << " Caused by: [" << cause->what() << "]";
00048     }
00049 
00050     if(msg.length()>0) {
00051       oss << " Message: [" << msg << "]";
00052     };
00053     text = oss.str();
00054     return text.c_str();
00055 }
00056 
00057 string AbstractThrowable::getMessage() const throw() {
00058     return msg;
00059 }
00060     
00061 const Throwable* AbstractThrowable::getCause() const throw() {
00062     return cause.get();
00063 }
00064     
00065 shared_ptr<Throwable> AbstractThrowable::clone() const throw() {
00066     return shared_ptr<Throwable>(new AbstractThrowable(*this));
00067 }
00068      
00069 void AbstractThrowable::initialize(const string& id, const string& name, 
00070                    const string& msg, Throwable* cause, 
00071                    const string& file, int line) throw() {
00072     this->id = id;
00073     this->name = name;
00074     if (msg.length() > 0) 
00075     this->msg = msg;
00076     else 
00077     this->msg = "Wrapped around";
00078     
00079     if (cause) this->cause = cause->clone();
00080     this->file = file;
00081     this->line = line;
00082     severity = MRS_ERROR;   //Default severity
00083 }
00084 
00085 //Exception methods    
00086 Exception::Exception(const string& msg, const string& file, int line) throw() {
00087     initialize("EXCEPTION", "Sct::Exception", msg, 0, file, line);
00088 }
00089     
00090 Exception::Exception(Throwable& cause, const string& file, int line) throw() {
00091     initialize("EXCEPTION", "Sct::Exception", "", &cause, file, line);
00092 }
00093     
00094 Exception::Exception(const string& msg, Throwable& cause, const string& file, int line) throw() {
00095     initialize("EXCEPTION", "Sct::Exception", msg, &cause, file, line);
00096 }
00097     
00098 
00099 //Error methods   
00100 Error::Error(const string& msg, const string& file, int line) throw() {
00101     initialize("ERROR", "Sct::Error", msg, 0, file, line);
00102 }
00103     
00104 Error::Error(Throwable& cause, const string& file, int line) throw() {
00105     initialize("ERROR", "Sct::Error", "", &cause, file, line);
00106 }
00107     
00108 Error::Error(const string& msg, Throwable& cause, const string& file, int line) throw() {
00109     initialize("ERROR", "Sct::Error", msg, &cause, file, line);    
00110 }
00111     
00112 
00113 
00114 //Stuff to deal with system-wide handling of exceptions
00115     
00116 //Prototypes
00117 void Terminate() throw();
00118 void Unexpected() throw();
00119     
00120 const char* process_name = 0;
00121 
00122 void setExceptionHandlers(const char* name) throw() {
00123     process_name=name;
00124     std::set_unexpected ( &Unexpected );
00125     std::set_terminate  ( &Terminate  );
00126 }
00127 
00128 
00135 void Terminate() throw() {
00136     static int callCount = 0;
00137     Throwable* mrs = 0;
00138     try {
00139         if (!callCount++) {
00140             throw;   // rethrow the last exception
00141         } else {
00142             cerr << "Damn annoying exception throw bug happened again" << endl;
00143         }
00144     } catch(Throwable &e) {
00145         e.sendToMrs(MRS_ERROR);
00146     } catch(CORBA::Exception& e) {
00147         mrs = new CorbaExceptionWrapper(e, "Caught corba exception", __FILE__, __LINE__); 
00148     } catch(std::exception &e) {
00149     mrs = new StdExceptionWrapper(e);
00150     } catch(std::string &s) {          // Just in case  
00151         std::ostringstream os;
00152         os<<"uncaught string expection "<<s;
00153         mrs = new Error(os.str(), __FILE__, __LINE__);
00154     }    catch(...) {
00155         mrs = new Error("uncaught unknown exception", __FILE__, __LINE__);
00156     }
00157     if (mrs) {
00158         mrs->sendToMrs(MRS_ERROR);
00159     } else {
00160     std::ostringstream os;
00161     os<<"Exception::Terminate() " << string(process_name);
00162     Error die(os.str(), __FILE__, __LINE__);
00163     die.sendToMrs(MRS_ERROR);
00164     }
00165     exit(EXIT_FAILURE);
00166 }
00167 
00168 
00174 void Unexpected() throw() {
00175     Error mrs("Exception::Unexpected()", __FILE__, __LINE__);
00176     mrs.sendToMrs(MRS_ERROR);
00177     terminate();
00178 }
00179 
00180 
00181 
00182 
00183 }  // end of namespace Sct

Generated on Mon Feb 6 14:01:19 2006 for SCT DAQ/DCS Software - C++ by  doxygen 1.4.6