00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #pragma once
00020
00021 #include "../db/lasterror.h"
00022
00023
00024 #ifdef __GNUC__
00025 # define MONGO_NORETURN __attribute__((__noreturn__))
00026 #else
00027 # define MONGO_NORETURN
00028 #endif
00029
00030 namespace mongo {
00031
00032 enum CommonErrorCodes {
00033 DatabaseDifferCaseCode = 13297 ,
00034 StaleConfigInContextCode = 13388
00035 };
00036
00037 class AssertionCount {
00038 public:
00039 AssertionCount();
00040 void rollover();
00041 void condrollover( int newValue );
00042
00043 int regular;
00044 int warning;
00045 int msg;
00046 int user;
00047 int rollovers;
00048 };
00049
00050 extern AssertionCount assertionCount;
00051
00052 struct ExceptionInfo {
00053 ExceptionInfo() : msg(""),code(-1) {}
00054 ExceptionInfo( const char * m , int c )
00055 : msg( m ) , code( c ) {
00056 }
00057 ExceptionInfo( const string& m , int c )
00058 : msg( m ) , code( c ) {
00059 }
00060 void append( BSONObjBuilder& b , const char * m = "$err" , const char * c = "code" ) const ;
00061 string toString() const { stringstream ss; ss << "exception: " << code << " " << msg; return ss.str(); }
00062 bool empty() const { return msg.empty(); }
00063
00064 void reset(){ msg = ""; code=-1; }
00065
00066 string msg;
00067 int code;
00068 };
00069
00076 class ErrorMsg {
00077 public:
00078 ErrorMsg(const char *msg, char ch);
00079 ErrorMsg(const char *msg, unsigned val);
00080 operator string() const { return buf; }
00081 private:
00082 char buf[256];
00083 };
00084
00085 class DBException : public std::exception {
00086 public:
00087 DBException( const ExceptionInfo& ei ) : _ei(ei) {}
00088 DBException( const char * msg , int code ) : _ei(msg,code) {}
00089 DBException( const string& msg , int code ) : _ei(msg,code) {}
00090 virtual ~DBException() throw() { }
00091
00092 virtual const char* what() const throw() { return _ei.msg.c_str(); }
00093 virtual int getCode() const { return _ei.code; }
00094
00095 virtual void appendPrefix( stringstream& ss ) const { }
00096
00097 virtual string toString() const {
00098 stringstream ss; ss << getCode() << " " << what(); return ss.str();
00099 return ss.str();
00100 }
00101
00102 const ExceptionInfo& getInfo() const { return _ei; }
00103
00104 protected:
00105 ExceptionInfo _ei;
00106 };
00107
00108 class AssertionException : public DBException {
00109 public:
00110
00111 AssertionException( const ExceptionInfo& ei ) : DBException(ei) {}
00112 AssertionException( const char * msg , int code ) : DBException(msg,code) {}
00113 AssertionException( const string& msg , int code ) : DBException(msg,code) {}
00114
00115 virtual ~AssertionException() throw() { }
00116
00117 virtual bool severe() { return true; }
00118 virtual bool isUserAssertion() { return false; }
00119
00120
00121 bool interrupted() {
00122 return _ei.code == 11600 || _ei.code == 11601;
00123 }
00124 };
00125
00126
00127 class UserException : public AssertionException {
00128 public:
00129 UserException(int c , const string& m) : AssertionException( m , c ) {}
00130
00131 virtual bool severe() { return false; }
00132 virtual bool isUserAssertion() { return true; }
00133 virtual void appendPrefix( stringstream& ss ) const { ss << "userassert:"; }
00134 };
00135
00136 class MsgAssertionException : public AssertionException {
00137 public:
00138 MsgAssertionException( const ExceptionInfo& ei ) : AssertionException( ei ) {}
00139 MsgAssertionException(int c, const string& m) : AssertionException( m , c ) {}
00140 virtual bool severe() { return false; }
00141 virtual void appendPrefix( stringstream& ss ) const { ss << "massert:"; }
00142 };
00143
00144 void asserted(const char *msg, const char *file, unsigned line) MONGO_NORETURN;
00145 void wasserted(const char *msg, const char *file, unsigned line);
00146 void verifyFailed( int msgid );
00147
00151 void uasserted(int msgid, const char *msg) MONGO_NORETURN;
00152 inline void uasserted(int msgid , string msg) { uasserted(msgid, msg.c_str()); }
00153
00155 void uassert_nothrow(const char *msg);
00156
00160 void msgassertedNoTrace(int msgid, const char *msg) MONGO_NORETURN;
00161 inline void msgassertedNoTrace(int msgid, const string& msg) { msgassertedNoTrace( msgid , msg.c_str() ); }
00162 void msgasserted(int msgid, const char *msg) MONGO_NORETURN;
00163 inline void msgasserted(int msgid, string msg) { msgasserted(msgid, msg.c_str()); }
00164
00165
00166 inline string causedBy( const char* e ){ return (string)" :: caused by :: " + e; }
00167 inline string causedBy( const DBException& e ){ return causedBy( e.toString().c_str() ); }
00168 inline string causedBy( const std::exception& e ){ return causedBy( e.what() ); }
00169 inline string causedBy( const string& e ){ return causedBy( e.c_str() ); }
00170
00172 inline void verify( int msgid , bool testOK ) { if ( ! testOK ) verifyFailed( msgid ); }
00173
00174 #ifdef assert
00175 #undef assert
00176 #endif
00177
00178 #define MONGO_assert(_Expression) (void)( MONGO_likely(!!(_Expression)) || (mongo::asserted(#_Expression, __FILE__, __LINE__), 0) )
00179 #define assert MONGO_assert
00180
00181
00182 #define MONGO_uassert(msgid, msg, expr) (void)( MONGO_likely(!!(expr)) || (mongo::uasserted(msgid, msg), 0) )
00183 #define uassert MONGO_uassert
00184
00185
00186 #define MONGO_wassert(_Expression) (void)( MONGO_likely(!!(_Expression)) || (mongo::wasserted(#_Expression, __FILE__, __LINE__), 0) )
00187 #define wassert MONGO_wassert
00188
00189
00190
00191
00192
00193
00194 #define MONGO_massert(msgid, msg, expr) (void)( MONGO_likely(!!(expr)) || (mongo::msgasserted(msgid, msg), 0) )
00195 #define massert MONGO_massert
00196
00197
00198
00199
00200 #if defined(_DEBUG)
00201 # define MONGO_dassert assert
00202 #else
00203 # define MONGO_dassert(x)
00204 #endif
00205 #define dassert MONGO_dassert
00206
00207
00208
00209
00210
00211
00212 enum { ASSERT_ID_DUPKEY = 11000 };
00213
00214
00215 void streamNotGood( int code , string msg , std::ios& myios ) MONGO_NORETURN;
00216
00217 inline void assertStreamGood(unsigned msgid, string msg, std::ios& myios) {
00218 if( !myios.good() ) streamNotGood(msgid, msg, myios);
00219 }
00220
00221 string demangleName( const type_info& typeinfo );
00222
00223 }
00224
00225 #define BOOST_CHECK_EXCEPTION MONGO_BOOST_CHECK_EXCEPTION
00226 #define MONGO_BOOST_CHECK_EXCEPTION( expression ) \
00227 try { \
00228 expression; \
00229 } catch ( const std::exception &e ) { \
00230 stringstream ss; \
00231 ss << "caught boost exception: " << e.what() << ' ' << __FILE__ << ' ' << __LINE__; \
00232 msgasserted( 13294 , ss.str() ); \
00233 } catch ( ... ) { \
00234 massert( 10437 , "unknown boost failed" , false ); \
00235 }
00236
00237 #define MONGO_BOOST_CHECK_EXCEPTION_WITH_MSG( expression, msg ) \
00238 try { \
00239 expression; \
00240 } catch ( const std::exception &e ) { \
00241 stringstream ss; \
00242 ss << msg << " caught boost exception: " << e.what(); \
00243 msgasserted( 14043 , ss.str() ); \
00244 } catch ( ... ) { \
00245 msgasserted( 14044 , string("unknown boost failed ") + msg ); \
00246 }
00247
00248 #define DESTRUCTOR_GUARD MONGO_DESTRUCTOR_GUARD
00249 #define MONGO_DESTRUCTOR_GUARD( expression ) \
00250 try { \
00251 expression; \
00252 } catch ( const std::exception &e ) { \
00253 problem() << "caught exception (" << e.what() << ") in destructor (" << __FUNCTION__ << ")" << endl; \
00254 } catch ( ... ) { \
00255 problem() << "caught unknown exception in destructor (" << __FUNCTION__ << ")" << endl; \
00256 }
00257
00258 #undef MONGO_NORETURN