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