00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "common/error.hpp"
00026 #include "common/util.hpp"
00027
00028 #include <exception>
00029 #include <typeinfo>
00030 #include <iostream>
00031
00032 using util::isnil;
00033 using std::exception;
00034
00035
00036 namespace lumiera
00037 {
00038
00039 namespace error
00040 {
00041
00047 inline const string default_usermsg (Error* exception_obj) throw()
00048 {
00049 return string("Sorry, Lumiera encountered an internal error. (")
00050 + typeid(*exception_obj).name() + ")";
00051 }
00052
00053
00054
00055 LUMIERA_ERROR_DEFINE (LOGIC , "internal logic broken");
00056 LUMIERA_ERROR_DEFINE (FATAL , "floundered");
00057 LUMIERA_ERROR_DEFINE (CONFIG , "misconfiguration");
00058 LUMIERA_ERROR_DEFINE (STATE , "unforseen state");
00059 LUMIERA_ERROR_DEFINE (INVALID , "invalid input or parameters");
00060 LUMIERA_ERROR_DEFINE (EXTERNAL , "failure in external service");
00061 LUMIERA_ERROR_DEFINE (ASSERTION, "assertion failure");
00062
00063 }
00064
00065 LUMIERA_ERROR_DEFINE (EXCEPTION, "generic Lumiera exception");
00066
00067
00068
00069
00071 Error::Error (string description, const char* id) throw()
00072 : std::exception (),
00073 id_ (id),
00074 msg_ (error::default_usermsg (this)),
00075 desc_ (description),
00076 cause_ ("")
00077 {
00078 lumiera_error_set (this->id_);
00079 }
00080
00081
00082 Error::Error (std::exception& cause,
00083 string description, const char* id) throw()
00084 : std::exception (),
00085 id_ (id),
00086 msg_ (error::default_usermsg (this)),
00087 desc_ (description),
00088 cause_ (extractCauseMsg(cause))
00089 {
00090 lumiera_error_set (this->id_);
00091 }
00092
00093
00095 Error::Error (const Error& ref) throw()
00096 : std::exception (),
00097 id_ (ref.id_),
00098 msg_ (ref.msg_),
00099 desc_ (ref.desc_),
00100 cause_ (extractCauseMsg(ref))
00101 { }
00102
00103
00104
00110 const char*
00111 Error::what() const throw()
00112 {
00113 if (isnil (this->what_))
00114 {
00115 what_ = string(id_);
00116 if (!isnil (desc_)) what_ += " ("+desc_+").";
00117 if (!isnil (cause_)) what_ += string(" -- caused by: ") + cause_;
00118 }
00119 return what_.c_str();
00120 }
00121
00122
00126 const string
00127 Error::extractCauseMsg (const exception& cause) throw()
00128 {
00129 const Error* err=dynamic_cast<const Error*> (&cause);
00130 if (err)
00131 {
00132 if (isnil (err->cause_))
00133 return cause.what();
00134 else
00135 return err->cause_;
00136 }
00137
00138
00139 return cause.what ();
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 namespace error
00170 {
00171
00172 void lumiera_unexpectedException () throw()
00173 {
00174 const char* is_halted
00175 = "### Lumiera halted due to an unexpected Error ###";
00176
00177 std::cerr << "\n" << is_halted << "\n\n";
00178 ERROR (NOBUG_ON, "%s", is_halted);
00179
00180 if (const char * errorstate = lumiera_error ())
00181 ERROR (NOBUG_ON, "last registered error was....\n%s", errorstate);
00182
00183 std::terminate();
00184 }
00185
00186 void assertion_terminate (const string& location)
00187 {
00188 throw Fatal (location, LUMIERA_ERROR_ASSERTION)
00189 .setUsermsg("Program terminated because of violating "
00190 "an internal consistency check.");
00191 }
00192
00193
00194 void install_unexpectedException_handler ()
00195 {
00196 std::set_unexpected (lumiera_unexpectedException);
00197 }
00198
00199 }
00200
00201 }