MongoDB C++ Driver legacy-1.0.1
Loading...
Searching...
No Matches
assert_util.h
1// assert_util.h
2
3/* Copyright 2009 10gen Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#pragma once
19
20#include <typeinfo>
21#include <string>
22
23#include "mongo/base/status.h" // NOTE: This is safe as utils depend on base
24#include "mongo/client/export_macros.h"
25#include "mongo/platform/compiler.h"
26#include "mongo/logger/log_severity.h"
27#include "mongo/logger/logger.h"
28#include "mongo/logger/logstream_builder.h"
29
30namespace mongo {
31
32 enum CommonErrorCodes {
33 OkCode = 0,
34 DatabaseDifferCaseCode = 13297 , // uassert( 13297 )
35 SendStaleConfigCode = 13388 , // uassert( 13388 )
36 RecvStaleConfigCode = 9996, // uassert( 9996 )
37 PrepareConfigsFailedCode = 13104, // uassert( 13104 )
38 NotMasterOrSecondaryCode = 13436, // uassert( 13436 )
39 NotMasterNoSlaveOkCode = 13435, // uassert( 13435 )
40 NotMaster = 10107, // uassert( 10107 )
41 };
42
43 class BSONObjBuilder;
44
45 struct MONGO_CLIENT_API ExceptionInfo {
46 ExceptionInfo() : msg(""),code(-1) {}
47 ExceptionInfo( const char * m , int c )
48 : msg( m ) , code( c ) {
49 }
50 ExceptionInfo( const std::string& m , int c )
51 : msg( m ) , code( c ) {
52 }
53 void append( BSONObjBuilder& b , const char * m = "$err" , const char * c = "code" ) const ;
54 std::string toString() const;
55 bool empty() const { return msg.empty(); }
56 void reset(){ msg = ""; code=-1; }
57 std::string msg;
58 int code;
59 };
60
67 class MONGO_CLIENT_API ErrorMsg {
68 public:
69 ErrorMsg(const char *msg, char ch);
70 ErrorMsg(const char *msg, unsigned val);
71 operator std::string() const { return buf; }
72 private:
73 char buf[256];
74 };
75
76 class DBException;
77 MONGO_CLIENT_API std::string MONGO_CLIENT_FUNC causedBy( const DBException& e );
78 MONGO_CLIENT_API std::string MONGO_CLIENT_FUNC causedBy( const std::string& e );
79
81 class MONGO_CLIENT_API DBException : public std::exception {
82 public:
83 DBException( const ExceptionInfo& ei ) : _ei(ei) {}
84 DBException( const char * msg , int code ) : _ei(msg,code) {}
85 DBException( const std::string& msg , int code ) : _ei(msg,code) {}
86 virtual ~DBException() throw() { }
87
88 virtual const char* what() const throw() { return _ei.msg.c_str(); }
89 virtual int getCode() const { return _ei.code; }
90 virtual void appendPrefix( std::stringstream& ss ) const { }
91 virtual void addContext( const std::string& str ) {
92 _ei.msg = str + causedBy( _ei.msg );
93 }
94
95 // Utilities for the migration to Status objects
96 static ErrorCodes::Error MONGO_CLIENT_FUNC convertExceptionCode(int exCode);
97
98 Status toStatus(const std::string& context) const {
99 return Status(convertExceptionCode(getCode()), context + causedBy(*this));
100 }
101 Status toStatus() const {
102 return Status(convertExceptionCode(getCode()), this->what());
103 }
104
105 // context when applicable. otherwise ""
106 std::string _shard;
107
108 virtual std::string toString() const;
109
110 const ExceptionInfo& getInfo() const { return _ei; }
111
112 protected:
113 ExceptionInfo _ei;
114 };
115
116 class MONGO_CLIENT_API AssertionException : public DBException {
117 public:
118
119 AssertionException( const ExceptionInfo& ei ) : DBException(ei) {}
120 AssertionException( const char * msg , int code ) : DBException(msg,code) {}
121 AssertionException( const std::string& msg , int code ) : DBException(msg,code) {}
122
123 virtual ~AssertionException() throw() { }
124
125 virtual bool severe() const { return true; }
126 virtual bool isUserAssertion() const { return false; }
127 };
128
129 /* UserExceptions are valid errors that a user can cause, like out of disk space or duplicate key */
130 class MONGO_CLIENT_API UserException : public AssertionException {
131 public:
132 UserException(int c , const std::string& m) : AssertionException( m , c ) {}
133 virtual bool severe() const { return false; }
134 virtual bool isUserAssertion() const { return true; }
135 virtual void appendPrefix( std::stringstream& ss ) const;
136 };
137
138 class MONGO_CLIENT_API MsgAssertionException : public AssertionException {
139 public:
141 MsgAssertionException(int c, const std::string& m) : AssertionException( m , c ) {}
142 virtual bool severe() const { return false; }
143 virtual void appendPrefix( std::stringstream& ss ) const;
144 };
145
146 MONGO_CLIENT_API MONGO_COMPILER_NORETURN void MONGO_CLIENT_FUNC verifyFailed(const char *expr, const char *file, unsigned line);
147 MONGO_CLIENT_API MONGO_COMPILER_NORETURN void MONGO_CLIENT_FUNC invariantFailed(const char *expr, const char *file, unsigned line);
148 MONGO_CLIENT_API MONGO_COMPILER_NORETURN void MONGO_CLIENT_FUNC invariantOKFailed(const char *expr, const Status& status, const char *file, unsigned line);
149 MONGO_CLIENT_API void MONGO_CLIENT_FUNC wasserted(const char *expr, const char *file, unsigned line);
150 MONGO_CLIENT_API MONGO_COMPILER_NORETURN void MONGO_CLIENT_FUNC fassertFailed( int msgid );
151 MONGO_CLIENT_API MONGO_COMPILER_NORETURN void MONGO_CLIENT_FUNC fassertFailedWithStatus(
152 int msgid, const Status& status);
153 MONGO_CLIENT_API MONGO_COMPILER_NORETURN void MONGO_CLIENT_FUNC fassertFailedWithStatusNoTrace(
154 int msgid, const Status& status);
155
159 MONGO_CLIENT_API MONGO_COMPILER_NORETURN void MONGO_CLIENT_FUNC uasserted(int msgid, const char *msg);
160 MONGO_CLIENT_API MONGO_COMPILER_NORETURN void MONGO_CLIENT_FUNC uasserted(int msgid , const std::string &msg);
161
165 MONGO_CLIENT_API MONGO_COMPILER_NORETURN void MONGO_CLIENT_FUNC msgassertedNoTrace(int msgid, const char *msg);
166 MONGO_CLIENT_API MONGO_COMPILER_NORETURN void MONGO_CLIENT_FUNC msgassertedNoTrace(int msgid, const std::string &msg);
167 MONGO_CLIENT_API MONGO_COMPILER_NORETURN void MONGO_CLIENT_FUNC msgasserted(int msgid, const char *msg);
168 MONGO_CLIENT_API MONGO_COMPILER_NORETURN void MONGO_CLIENT_FUNC msgasserted(int msgid, const std::string &msg);
169
170 /* convert various types of exceptions to strings */
171 MONGO_CLIENT_API std::string MONGO_CLIENT_FUNC causedBy( const char* e );
172 MONGO_CLIENT_API std::string MONGO_CLIENT_FUNC causedBy( const DBException& e );
173 MONGO_CLIENT_API std::string MONGO_CLIENT_FUNC causedBy( const std::exception& e );
174 MONGO_CLIENT_API std::string MONGO_CLIENT_FUNC causedBy( const std::string& e );
175 MONGO_CLIENT_API std::string MONGO_CLIENT_FUNC causedBy( const std::string* e );
176 MONGO_CLIENT_API std::string MONGO_CLIENT_FUNC causedBy( const Status& e );
177
179 MONGO_CLIENT_API inline void MONGO_CLIENT_FUNC fassert(int msgid, bool testOK) {
180 if (MONGO_unlikely(!testOK)) fassertFailed(msgid);
181 }
182
183 MONGO_CLIENT_API inline void MONGO_CLIENT_FUNC fassert(int msgid, const Status& status) {
184 if (MONGO_unlikely(!status.isOK())) {
185 fassertFailedWithStatus(msgid, status);
186 }
187 }
188
189 MONGO_CLIENT_API inline void fassertNoTrace(int msgid, const Status& status) {
190 if (MONGO_unlikely(!status.isOK())) {
191 fassertFailedWithStatusNoTrace(msgid, status);
192 }
193 }
194
195
196 /* "user assert". if asserts, user did something wrong, not our code */
197#define MONGO_uassert(msgid, msg, expr) do { \
198 if (MONGO_unlikely(!(expr))) { \
199 ::mongo::uasserted(msgid, msg); \
200 } \
201 } while (false)
202
203 MONGO_CLIENT_API inline void MONGO_CLIENT_FUNC uassertStatusOK(const Status& status) {
204 if (MONGO_unlikely(!status.isOK())) {
205 uasserted((status.location() != 0 ? status.location() : status.code()),
206 status.reason());
207 }
208 }
209
210 /* warning only - keeps going */
211#define MONGO_wassert(_Expression) do { \
212 if (MONGO_unlikely(!(_Expression))) { \
213 ::mongo::wasserted(#_Expression, __FILE__, __LINE__); \
214 } \
215 } while (false)
216
217 /* display a message, no context, and throw assertionexception
218
219 easy way to throw an exception and log something without our stack trace
220 display happening.
221 */
222#define MONGO_massert(msgid, msg, expr) do { \
223 if (MONGO_unlikely(!(expr))) { \
224 ::mongo::msgasserted(msgid, msg); \
225 } \
226 } while (false)
227
228 MONGO_CLIENT_API inline void massertStatusOK(const Status& status) {
229 if (MONGO_unlikely(!status.isOK())) {
230 msgasserted((status.location() != 0 ? status.location() : status.code()),
231 status.reason());
232 }
233 }
234
235 MONGO_CLIENT_API inline void massertNoTraceStatusOK(const Status& status) {
236 if (MONGO_unlikely(!status.isOK())) {
237 msgassertedNoTrace((status.location() != 0 ? status.location() : status.code()),
238 status.reason());
239 }
240 }
241
242 /* same as massert except no msgid */
243#define MONGO_verify(_Expression) do { \
244 if (MONGO_unlikely(!(_Expression))) { \
245 ::mongo::verifyFailed(#_Expression, __FILE__, __LINE__); \
246 } \
247 } while (false)
248
249#define MONGO_invariant(_Expression) do { \
250 if (MONGO_unlikely(!(_Expression))) { \
251 ::mongo::invariantFailed(#_Expression, __FILE__, __LINE__); \
252 } \
253 } while (false)
254
255#define MONGO_invariantOK(expression) do { \
256 const ::mongo::Status _invariantOK_status = expression; \
257 if (MONGO_unlikely(!_invariantOK_status.isOK())) { \
258 ::mongo::invariantOKFailed(#expression, _invariantOK_status, __FILE__, __LINE__); \
259 } \
260 } while (false)
261
262#ifdef MONGO_EXPOSE_MACROS
263# define verify(expression) MONGO_verify(expression)
264# define invariant MONGO_invariant
265# define invariantOK MONGO_invariantOK
266# define uassert MONGO_uassert
267# define wassert MONGO_wassert
268# define massert MONGO_massert
269#endif
270
271 // some special ids that we want to duplicate
272
273 // > 10000 asserts
274 // < 10000 UserException
275
276 enum { ASSERT_ID_DUPKEY = 11000 };
277
278 std::string demangleName( const std::type_info& typeinfo );
279
280} // namespace mongo
281
282#define MONGO_ASSERT_ON_EXCEPTION( expression ) \
283 try { \
284 expression; \
285 } catch ( const std::exception &e ) { \
286 std::stringstream ss; \
287 ss << "caught exception: " << e.what() << ' ' << __FILE__ << ' ' << __LINE__; \
288 msgasserted( 13294 , ss.str() ); \
289 } catch ( ... ) { \
290 massert( 10437 , "unknown exception" , false ); \
291 }
292
293#define MONGO_ASSERT_ON_EXCEPTION_WITH_MSG( expression, msg ) \
294 try { \
295 expression; \
296 } catch ( const std::exception &e ) { \
297 std::stringstream ss; \
298 ss << msg << " caught exception exception: " << e.what(); \
299 msgasserted( 14043 , ss.str() ); \
300 } catch ( ... ) { \
301 msgasserted( 14044 , std::string("unknown exception") + msg ); \
302 }
303
304#define DESTRUCTOR_GUARD MONGO_DESTRUCTOR_GUARD
305#define MONGO_DESTRUCTOR_GUARD( expression ) \
306 try { \
307 expression; \
308 } catch ( const std::exception &e ) { \
309 ::mongo::logger::LogstreamBuilder(::mongo::logger::globalLogDomain(), \
310 std::string(), \
311 ::mongo::logger::LogSeverity::Log()) \
312 << "caught exception (" << e.what() << ") in destructor (" << __FUNCTION__ \
313 << ")" << std::endl; \
314 } catch ( ... ) { \
315 ::mongo::logger::LogstreamBuilder(::mongo::logger::globalLogDomain(), \
316 std::string(), \
317 ::mongo::logger::LogSeverity::Log()) \
318 << "caught unknown exception in destructor (" << __FUNCTION__ << ")" \
319 << std::endl; \
320 }
321
Definition assert_util.h:116
Utility for creating a BSONObj.
Definition bsonobjbuilder.h:53
Most mongo exceptions inherit from this; this is commonly caught in most threads.
Definition assert_util.h:81
helper class that builds error strings.
Definition assert_util.h:67
Definition assert_util.h:138
Definition assert_util.h:130
the main MongoDB namespace
Definition bulk_operation_builder.h:24
MONGO_CLIENT_API MONGO_COMPILER_NORETURN void MONGO_CLIENT_FUNC uasserted(int msgid, const char *msg)
a "user assertion".
MONGO_CLIENT_API void MONGO_CLIENT_FUNC fassert(int msgid, bool testOK)
aborts on condition failure
Definition assert_util.h:179
MONGO_CLIENT_API Status(MONGO_CLIENT_FUNC *saslClientAuthenticate)(DBClientWithCommands *client
Attempts to authenticate "client" using the SASL protocol.
MONGO_CLIENT_API MONGO_COMPILER_NORETURN void MONGO_CLIENT_FUNC msgassertedNoTrace(int msgid, const char *msg)
msgassert and massert are for errors that are internal but have a well defined error text std::string...
Definition assert_util.h:45