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 namespace mongo {
00024
00025 enum CommonErrorCodes {
00026 DatabaseDifferCaseCode = 13297 ,
00027 StaleConfigInContextCode = 13388
00028 };
00029
00030 class AssertionCount {
00031 public:
00032 AssertionCount();
00033 void rollover();
00034 void condrollover( int newValue );
00035
00036 int regular;
00037 int warning;
00038 int msg;
00039 int user;
00040 int rollovers;
00041 };
00042
00043 extern AssertionCount assertionCount;
00044
00045 struct ExceptionInfo {
00046 ExceptionInfo() : msg(""),code(-1) {}
00047 ExceptionInfo( const char * m , int c )
00048 : msg( m ) , code( c ) {
00049 }
00050 ExceptionInfo( const string& m , int c )
00051 : msg( m ) , code( c ) {
00052 }
00053 void append( BSONObjBuilder& b , const char * m = "$err" , const char * c = "code" ) const ;
00054 string toString() const { stringstream ss; ss << "exception: " << code << " " << msg; return ss.str(); }
00055 bool empty() const { return msg.empty(); }
00056
00057 string msg;
00058 int code;
00059 };
00060
00061 class DBException : public std::exception {
00062 public:
00063 DBException( const ExceptionInfo& ei ) : _ei(ei) {}
00064 DBException( const char * msg , int code ) : _ei(msg,code) {}
00065 DBException( const string& msg , int code ) : _ei(msg,code) {}
00066 virtual ~DBException() throw() { }
00067
00068 virtual const char* what() const throw() { return _ei.msg.c_str(); }
00069 virtual int getCode() const { return _ei.code; }
00070
00071 virtual void appendPrefix( stringstream& ss ) const { }
00072
00073 virtual string toString() const {
00074 stringstream ss; ss << getCode() << " " << what(); return ss.str();
00075 return ss.str();
00076 }
00077
00078 const ExceptionInfo& getInfo() const { return _ei; }
00079
00080 protected:
00081 ExceptionInfo _ei;
00082 };
00083
00084 class AssertionException : public DBException {
00085 public:
00086
00087 AssertionException( const ExceptionInfo& ei ) : DBException(ei) {}
00088 AssertionException( const char * msg , int code ) : DBException(msg,code) {}
00089 AssertionException( const string& msg , int code ) : DBException(msg,code) {}
00090
00091 virtual ~AssertionException() throw() { }
00092
00093 virtual bool severe() { return true; }
00094 virtual bool isUserAssertion() { return false; }
00095
00096
00097 bool interrupted() {
00098 return _ei.code == 11600 || _ei.code == 11601;
00099 }
00100 };
00101
00102
00103 class UserException : public AssertionException {
00104 public:
00105 UserException(int c , const string& m) : AssertionException( m , c ) {}
00106
00107 virtual bool severe() { return false; }
00108 virtual bool isUserAssertion() { return true; }
00109 virtual void appendPrefix( stringstream& ss ) const { ss << "userassert:"; }
00110 };
00111
00112 class MsgAssertionException : public AssertionException {
00113 public:
00114 MsgAssertionException( const ExceptionInfo& ei ) : AssertionException( ei ) {}
00115 MsgAssertionException(int c, const string& m) : AssertionException( m , c ) {}
00116 virtual bool severe() { return false; }
00117 virtual void appendPrefix( stringstream& ss ) const { ss << "massert:"; }
00118 };
00119
00120
00121 void asserted(const char *msg, const char *file, unsigned line);
00122 void wasserted(const char *msg, const char *file, unsigned line);
00123
00127 void uasserted(int msgid, const char *msg);
00128 inline void uasserted(int msgid , string msg) { uasserted(msgid, msg.c_str()); }
00129
00131 void uassert_nothrow(const char *msg);
00132
00136 void msgassertedNoTrace(int msgid, const char *msg);
00137 inline void msgassertedNoTrace(int msgid, const string& msg) { msgassertedNoTrace( msgid , msg.c_str() ); }
00138 void msgasserted(int msgid, const char *msg);
00139 inline void msgasserted(int msgid, string msg) { msgasserted(msgid, msg.c_str()); }
00140
00141 #ifdef assert
00142 #undef assert
00143 #endif
00144
00145 #define MONGO_assert(_Expression) (void)( (!!(_Expression)) || (mongo::asserted(#_Expression, __FILE__, __LINE__), 0) )
00146 #define assert MONGO_assert
00147
00148
00149 #define MONGO_uassert(msgid, msg, expr) (void)( (!!(expr)) || (mongo::uasserted(msgid, msg), 0) )
00150 #define uassert MONGO_uassert
00151
00152
00153 #define MONGO_wassert(_Expression) (void)( (!!(_Expression)) || (mongo::wasserted(#_Expression, __FILE__, __LINE__), 0) )
00154 #define wassert MONGO_wassert
00155
00156
00157
00158
00159
00160
00161 #define MONGO_massert(msgid, msg, expr) (void)( (!!(expr)) || (mongo::msgasserted(msgid, msg), 0) )
00162 #define massert MONGO_massert
00163
00164
00165
00166
00167 #if defined(_DEBUG)
00168 # define MONGO_dassert assert
00169 #else
00170 # define MONGO_dassert(x)
00171 #endif
00172 #define dassert MONGO_dassert
00173
00174
00175
00176
00177
00178
00179 enum { ASSERT_ID_DUPKEY = 11000 };
00180
00181
00182 void streamNotGood( int code , string msg , std::ios& myios );
00183
00184 inline void assertStreamGood(unsigned msgid, string msg, std::ios& myios) {
00185 if( !myios.good() ) streamNotGood(msgid, msg, myios);
00186 }
00187
00188 string demangleName( const type_info& typeinfo );
00189
00190 }
00191
00192 #define BOOST_CHECK_EXCEPTION MONGO_BOOST_CHECK_EXCEPTION
00193 #define MONGO_BOOST_CHECK_EXCEPTION( expression ) \
00194 try { \
00195 expression; \
00196 } catch ( const std::exception &e ) { \
00197 stringstream ss; \
00198 ss << "caught boost exception: " << e.what(); \
00199 msgasserted( 13294 , ss.str() ); \
00200 } catch ( ... ) { \
00201 massert( 10437 , "unknown boost failed" , false ); \
00202 }
00203
00204 #define DESTRUCTOR_GUARD MONGO_DESTRUCTOR_GUARD
00205 #define MONGO_DESTRUCTOR_GUARD( expression ) \
00206 try { \
00207 expression; \
00208 } catch ( const std::exception &e ) { \
00209 problem() << "caught exception (" << e.what() << ") in destructor (" << __FUNCTION__ << ")" << endl; \
00210 } catch ( ... ) { \
00211 problem() << "caught unknown exception in destructor (" << __FUNCTION__ << ")" << endl; \
00212 }