summaryrefslogtreecommitdiff
path: root/src/mongo/db/lasterror.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/lasterror.cpp')
-rw-r--r--src/mongo/db/lasterror.cpp156
1 files changed, 102 insertions, 54 deletions
diff --git a/src/mongo/db/lasterror.cpp b/src/mongo/db/lasterror.cpp
index d242cdedc1a..d0a22d56b51 100644
--- a/src/mongo/db/lasterror.cpp
+++ b/src/mongo/db/lasterror.cpp
@@ -27,91 +27,139 @@
* then also delete it in the license file.
*/
+#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault
+
#include "mongo/platform/basic.h"
#include "mongo/db/lasterror.h"
#include "mongo/db/jsobj.h"
-#include "mongo/util/assert_util.h"
+#include "mongo/util/debug_util.h"
+#include "mongo/util/log.h"
+#include "mongo/util/net/message.h"
namespace mongo {
- LastError LastError::noError;
-
- const Client::Decoration<LastError> LastError::get = Client::declareDecoration<LastError>();
-
- void LastError::reset(bool valid) {
- *this = LastError();
- _valid = valid;
- }
+ using std::endl;
- void LastError::setLastError(int code, std::string msg) {
- if (_disabled) {
- return;
+ LastError LastError::noError;
+ LastErrorHolder lastError;
+
+ bool isShell = false;
+ void setLastError(int code , const char *msg) {
+ LastError *le = lastError.get();
+ if ( le == 0 ) {
+ /* might be intentional (non-user thread) */
+ DEV {
+ static unsigned n;
+ if( ++n < 4 && !isShell ) log() << "dev: lastError==0 won't report:" << msg << endl;
+ }
+ }
+ else if ( le->disabled ) {
+ log() << "lastError disabled, can't report: " << code << ":" << msg << endl;
+ }
+ else {
+ le->raiseError(code, msg);
}
- reset(true);
- _code = code;
- _msg = std::move(msg);
- }
-
- void LastError::recordInsert(long long nObjects) {
- reset(true);
- _nObjects = nObjects;
- }
-
- void LastError::recordUpdate(bool updateObjects, long long nObjects, BSONObj upsertedId) {
- reset(true);
- _nObjects = nObjects;
- _updatedExisting = updateObjects ? True : False;
- if ( upsertedId.valid() && upsertedId.hasField(kUpsertedFieldName) )
- _upsertedId = upsertedId;
- }
-
- void LastError::recordDelete(long long nDeleted) {
- reset(true);
- _nObjects = nDeleted;
}
- bool LastError::appendSelf(BSONObjBuilder &b , bool blankErr) const {
+ bool LastError::appendSelf( BSONObjBuilder &b , bool blankErr ) {
- if (!_valid) {
- if (blankErr)
+ if ( !valid ) {
+ if ( blankErr )
b.appendNull( "err" );
b.append( "n", 0 );
return false;
}
- if (_msg.empty()) {
- if (blankErr) {
+ if ( msg.empty() ) {
+ if ( blankErr ) {
b.appendNull( "err" );
}
}
else {
- b.append("err", _msg);
+ b.append( "err", msg );
}
- if (_code)
- b.append("code" , _code);
- if (_updatedExisting != NotUpdate)
- b.appendBool("updatedExisting", _updatedExisting == True);
- if (!_upsertedId.isEmpty()) {
- b.append(_upsertedId[kUpsertedFieldName]);
+ if ( code )
+ b.append( "code" , code );
+ if ( updatedExisting != NotUpdate )
+ b.appendBool( "updatedExisting", updatedExisting == True );
+ if ( !upsertedId.isEmpty() ) {
+ b.append( upsertedId[kUpsertedFieldName] );
}
- b.appendNumber("n", _nObjects);
+ b.appendNumber( "n", nObjects );
+
+ return ! msg.empty();
+ }
- return !_msg.empty();
+ LastErrorHolder::~LastErrorHolder() {
}
- void LastError::disable() {
- invariant(!_disabled);
- _disabled = true;
- _nPrev--; // caller is a command that shouldn't count as an operation
+ LastError * LastErrorHolder::disableForCommand() {
+ LastError *le = _get();
+ uassert(13649, "no operation yet", le);
+ le->disabled = true;
+ le->nPrev--; // caller is a command that shouldn't count as an operation
+ return le;
+ }
+
+ LastError * LastErrorHolder::get( bool create ) {
+ LastError *ret = _get( create );
+ if ( ret && !ret->disabled )
+ return ret;
+ return 0;
+ }
+
+ LastError * LastErrorHolder::getSafe() {
+ LastError * le = get(false);
+ if ( ! le ) {
+ error() << " no LastError!" << std::endl;
+ verify( le );
+ }
+ return le;
+ }
+
+ LastError * LastErrorHolder::_get( bool create ) {
+ LastError * le = _tl.get();
+ if ( ! le && create ) {
+ le = new LastError();
+ _tl.reset( le );
+ }
+ return le;
+ }
+
+ void LastErrorHolder::release() {
+ _tl.release();
+ }
+
+ /** ok to call more than once. */
+ void LastErrorHolder::initThread() {
+ if( ! _tl.get() )
+ _tl.reset( new LastError() );
+ }
+
+ void LastErrorHolder::reset( LastError * le ) {
+ _tl.reset( le );
+ }
+
+ void prepareErrForNewRequest( Message &m, LastError * err ) {
+ // a killCursors message shouldn't affect last error
+ verify( err );
+ if ( m.operation() == dbKillCursors ) {
+ err->disabled = true;
+ }
+ else {
+ err->disabled = false;
+ err->nPrev++;
+ }
}
- void LastError::startRequest() {
- _disabled = false;
- ++_nPrev;
+ LastError * LastErrorHolder::startRequest( Message& m , LastError * le ) {
+ verify( le );
+ prepareErrForNewRequest( m, le );
+ return le;
}
} // namespace mongo