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;
00083 }
00084
00085
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
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
00115
00116
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;
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) {
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 }