diff options
author | Antonin Kral <a.kral@bobek.cz> | 2011-09-14 17:08:06 +0200 |
---|---|---|
committer | Antonin Kral <a.kral@bobek.cz> | 2011-09-14 17:08:06 +0200 |
commit | 5d342a758c6095b4d30aba0750b54f13b8916f51 (patch) | |
tree | 762e9aa84781f5e3b96db2c02d356c29cf0217c0 /util/assert_util.h | |
parent | cbe2d992e9cd1ea66af9fa91df006106775d3073 (diff) | |
download | mongodb-5d342a758c6095b4d30aba0750b54f13b8916f51.tar.gz |
Imported Upstream version 2.0.0
Diffstat (limited to 'util/assert_util.h')
-rw-r--r-- | util/assert_util.h | 76 |
1 files changed, 61 insertions, 15 deletions
diff --git a/util/assert_util.h b/util/assert_util.h index 151e950..b4c68b7 100644 --- a/util/assert_util.h +++ b/util/assert_util.h @@ -20,6 +20,13 @@ #include "../db/lasterror.h" +// MONGO_NORETURN undefed at end of file +#ifdef __GNUC__ +# define MONGO_NORETURN __attribute__((__noreturn__)) +#else +# define MONGO_NORETURN +#endif + namespace mongo { enum CommonErrorCodes { @@ -53,11 +60,28 @@ namespace mongo { void append( BSONObjBuilder& b , const char * m = "$err" , const char * c = "code" ) const ; string toString() const { stringstream ss; ss << "exception: " << code << " " << msg; return ss.str(); } bool empty() const { return msg.empty(); } + + void reset(){ msg = ""; code=-1; } string msg; int code; }; + /** helper class that builds error strings. lighter weight than a StringBuilder, albeit less flexible. + NOINLINE_DECL used in the constructor implementations as we are assuming this is a cold code path when used. + + example: + throw UserException(123, ErrorMsg("blah", num_val)); + */ + class ErrorMsg { + public: + ErrorMsg(const char *msg, char ch); + ErrorMsg(const char *msg, unsigned val); + operator string() const { return buf; } + private: + char buf[256]; + }; + class DBException : public std::exception { public: DBException( const ExceptionInfo& ei ) : _ei(ei) {} @@ -117,14 +141,14 @@ namespace mongo { virtual void appendPrefix( stringstream& ss ) const { ss << "massert:"; } }; - - void asserted(const char *msg, const char *file, unsigned line); + void asserted(const char *msg, const char *file, unsigned line) MONGO_NORETURN; void wasserted(const char *msg, const char *file, unsigned line); - + void verifyFailed( int msgid ); + /** a "user assertion". throws UserAssertion. logs. typically used for errors that a user - could cause, such as dupliate key, disk full, etc. + could cause, such as duplicate key, disk full, etc. */ - void uasserted(int msgid, const char *msg); + void uasserted(int msgid, const char *msg) MONGO_NORETURN; inline void uasserted(int msgid , string msg) { uasserted(msgid, msg.c_str()); } /** reported via lasterror, but don't throw exception */ @@ -133,24 +157,33 @@ namespace mongo { /** msgassert and massert are for errors that are internal but have a well defined error text string. a stack trace is logged. */ - void msgassertedNoTrace(int msgid, const char *msg); + void msgassertedNoTrace(int msgid, const char *msg) MONGO_NORETURN; inline void msgassertedNoTrace(int msgid, const string& msg) { msgassertedNoTrace( msgid , msg.c_str() ); } - void msgasserted(int msgid, const char *msg); + void msgasserted(int msgid, const char *msg) MONGO_NORETURN; inline void msgasserted(int msgid, string msg) { msgasserted(msgid, msg.c_str()); } + /* convert various types of exceptions to strings */ + inline string causedBy( const char* e ){ return (string)" :: caused by :: " + e; } + inline string causedBy( const DBException& e ){ return causedBy( e.toString().c_str() ); } + inline string causedBy( const std::exception& e ){ return causedBy( e.what() ); } + inline string causedBy( const string& e ){ return causedBy( e.c_str() ); } + + /** in the mongodb source, use verify() instead of assert(). verify is always evaluated even in release builds. */ + inline void verify( int msgid , bool testOK ) { if ( ! testOK ) verifyFailed( msgid ); } + #ifdef assert #undef assert #endif -#define MONGO_assert(_Expression) (void)( (!!(_Expression)) || (mongo::asserted(#_Expression, __FILE__, __LINE__), 0) ) +#define MONGO_assert(_Expression) (void)( MONGO_likely(!!(_Expression)) || (mongo::asserted(#_Expression, __FILE__, __LINE__), 0) ) #define assert MONGO_assert /* "user assert". if asserts, user did something wrong, not our code */ -#define MONGO_uassert(msgid, msg, expr) (void)( (!!(expr)) || (mongo::uasserted(msgid, msg), 0) ) +#define MONGO_uassert(msgid, msg, expr) (void)( MONGO_likely(!!(expr)) || (mongo::uasserted(msgid, msg), 0) ) #define uassert MONGO_uassert /* warning only - keeps going */ -#define MONGO_wassert(_Expression) (void)( (!!(_Expression)) || (mongo::wasserted(#_Expression, __FILE__, __LINE__), 0) ) +#define MONGO_wassert(_Expression) (void)( MONGO_likely(!!(_Expression)) || (mongo::wasserted(#_Expression, __FILE__, __LINE__), 0) ) #define wassert MONGO_wassert /* display a message, no context, and throw assertionexception @@ -158,7 +191,7 @@ namespace mongo { easy way to throw an exception and log something without our stack trace display happening. */ -#define MONGO_massert(msgid, msg, expr) (void)( (!!(expr)) || (mongo::msgasserted(msgid, msg), 0) ) +#define MONGO_massert(msgid, msg, expr) (void)( MONGO_likely(!!(expr)) || (mongo::msgasserted(msgid, msg), 0) ) #define massert MONGO_massert /* dassert is 'debug assert' -- might want to turn off for production as these @@ -179,7 +212,7 @@ namespace mongo { enum { ASSERT_ID_DUPKEY = 11000 }; /* throws a uassertion with an appropriate msg */ - void streamNotGood( int code , string msg , std::ios& myios ); + void streamNotGood( int code , string msg , std::ios& myios ) MONGO_NORETURN; inline void assertStreamGood(unsigned msgid, string msg, std::ios& myios) { if( !myios.good() ) streamNotGood(msgid, msg, myios); @@ -195,10 +228,21 @@ namespace mongo { expression; \ } catch ( const std::exception &e ) { \ stringstream ss; \ - ss << "caught boost exception: " << e.what(); \ - msgasserted( 13294 , ss.str() ); \ + ss << "caught boost exception: " << e.what() << ' ' << __FILE__ << ' ' << __LINE__; \ + msgasserted( 13294 , ss.str() ); \ + } catch ( ... ) { \ + massert( 10437 , "unknown boost failed" , false ); \ + } + +#define MONGO_BOOST_CHECK_EXCEPTION_WITH_MSG( expression, msg ) \ + try { \ + expression; \ + } catch ( const std::exception &e ) { \ + stringstream ss; \ + ss << msg << " caught boost exception: " << e.what(); \ + msgasserted( 14043 , ss.str() ); \ } catch ( ... ) { \ - massert( 10437 , "unknown boost failed" , false ); \ + msgasserted( 14044 , string("unknown boost failed ") + msg ); \ } #define DESTRUCTOR_GUARD MONGO_DESTRUCTOR_GUARD @@ -210,3 +254,5 @@ namespace mongo { } catch ( ... ) { \ problem() << "caught unknown exception in destructor (" << __FUNCTION__ << ")" << endl; \ } + +#undef MONGO_NORETURN |