summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorMathias Stearn <mathias@10gen.com>2017-08-01 09:35:39 -0400
committerMathias Stearn <mathias@10gen.com>2017-08-16 16:28:02 -0400
commit40036f67d0c15e2cd319e82f8c6a1e691fb74806 (patch)
treefd9744b756fb092c47c1b3fbcd15e349fe0e270a /src/mongo
parent53a9b329fbf1a6d8b620fee2cbb2ef1c27ddd3f3 (diff)
downloadmongo-40036f67d0c15e2cd319e82f8c6a1e691fb74806.tar.gz
SERVER-30580 No more status locations
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/base/parse_number.cpp2
-rw-r--r--src/mongo/base/status-inl.h4
-rw-r--r--src/mongo/base/status.cpp45
-rw-r--r--src/mongo/base/status.h54
-rw-r--r--src/mongo/base/status_test.cpp10
-rw-r--r--src/mongo/base/status_with.h17
-rw-r--r--src/mongo/db/auth/authorization_manager.cpp3
-rwxr-xr-xsrc/mongo/db/auth/generate_action_types.py3
-rw-r--r--src/mongo/db/auth/role_graph.cpp54
-rw-r--r--src/mongo/db/auth/user_document_parser.cpp44
-rw-r--r--src/mongo/db/catalog/collection.h32
-rw-r--r--src/mongo/db/catalog/collection_impl.cpp63
-rw-r--r--src/mongo/db/catalog/collection_impl.h16
-rw-r--r--src/mongo/db/catalog/collection_mock.h16
-rw-r--r--src/mongo/db/exec/update.cpp107
-rw-r--r--src/mongo/db/exec/update.h24
-rw-r--r--src/mongo/db/pipeline/parsed_add_fields.cpp6
-rw-r--r--src/mongo/db/pipeline/parsed_aggregation_projection.cpp101
-rw-r--r--src/mongo/db/pipeline/parsed_aggregation_projection.h25
-rw-r--r--src/mongo/db/pipeline/pipeline.cpp68
-rw-r--r--src/mongo/db/pipeline/pipeline.h16
-rw-r--r--src/mongo/db/pipeline/pipeline_test.cpp6
-rw-r--r--src/mongo/db/repl/rs_rollback.cpp5
-rw-r--r--src/mongo/db/repl/rs_rollback_no_uuid.cpp8
-rw-r--r--src/mongo/db/repl/rs_rollback_no_uuid_test.cpp31
-rw-r--r--src/mongo/db/repl/rs_rollback_test.cpp24
-rw-r--r--src/mongo/db/storage/mmap_v1/btree/btree_logic.cpp4
-rw-r--r--src/mongo/db/storage/mmap_v1/record_store_v1_capped.cpp6
-rw-r--r--src/mongo/db/storage/mmap_v1/record_store_v1_capped_test.cpp4
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp13
-rw-r--r--src/mongo/db/views/durable_view_catalog.cpp17
-rw-r--r--src/mongo/dbtests/multikey_paths_test.cpp19
-rw-r--r--src/mongo/dbtests/query_stage_count.cpp18
-rw-r--r--src/mongo/dbtests/query_stage_sort.cpp15
-rw-r--r--src/mongo/logger/redaction.cpp2
-rw-r--r--src/mongo/logger/redaction_test.cpp6
-rw-r--r--src/mongo/s/client/shard_remote.cpp2
-rw-r--r--src/mongo/util/assert_util.h16
38 files changed, 374 insertions, 532 deletions
diff --git a/src/mongo/base/parse_number.cpp b/src/mongo/base/parse_number.cpp
index b9c81807b19..1c72e73db71 100644
--- a/src/mongo/base/parse_number.cpp
+++ b/src/mongo/base/parse_number.cpp
@@ -124,7 +124,7 @@ Status parseNumberFromStringWithBase(StringData stringValue, int base, NumberTyp
typedef ::std::numeric_limits<NumberType> limits;
if (base == 1 || base < 0 || base > 36)
- return Status(ErrorCodes::BadValue, "Invalid base", 0);
+ return Status(ErrorCodes::BadValue, "Invalid base");
bool isNegative = false;
StringData str = _extractBase(_extractSign(stringValue, &isNegative), base, &base);
diff --git a/src/mongo/base/status-inl.h b/src/mongo/base/status-inl.h
index a29678e67b2..7f69436834b 100644
--- a/src/mongo/base/status-inl.h
+++ b/src/mongo/base/status-inl.h
@@ -75,10 +75,6 @@ inline std::string Status::reason() const {
return _error ? _error->reason : std::string();
}
-inline int Status::location() const {
- return _error ? _error->location : 0;
-}
-
inline AtomicUInt32::WordType Status::refCount() const {
return _error ? _error->refs.load() : 0;
}
diff --git a/src/mongo/base/status.cpp b/src/mongo/base/status.cpp
index 2eef1946e75..57aedd11749 100644
--- a/src/mongo/base/status.cpp
+++ b/src/mongo/base/status.cpp
@@ -33,49 +33,24 @@
namespace mongo {
-Status::ErrorInfo::ErrorInfo(ErrorCodes::Error aCode, std::string aReason, int aLocation)
- : code(aCode), reason(std::move(aReason)), location(aLocation) {}
+Status::ErrorInfo::ErrorInfo(ErrorCodes::Error aCode, std::string aReason)
+ : code(aCode), reason(std::move(aReason)) {}
-Status::ErrorInfo* Status::ErrorInfo::create(ErrorCodes::Error c, std::string r, int l) {
+Status::ErrorInfo* Status::ErrorInfo::create(ErrorCodes::Error c, std::string r) {
if (c == ErrorCodes::OK)
return nullptr;
- return new ErrorInfo(c, std::move(r), l);
+ return new ErrorInfo(c, std::move(r));
}
-Status::Status(ErrorCodes::Error code, std::string reason, int location)
- : _error(ErrorInfo::create(code, std::move(reason), location)) {
+Status::Status(ErrorCodes::Error code, std::string reason)
+ : _error(ErrorInfo::create(code, std::move(reason))) {
ref(_error);
}
-Status::Status(ErrorCodes::Error code, const char* reason, int location)
- : Status(code, std::string(reason), location) {}
+Status::Status(ErrorCodes::Error code, const char* reason) : Status(code, std::string(reason)) {}
-Status::Status(ErrorCodes::Error code, const mongoutils::str::stream& reason, int location)
- : Status(code, std::string(reason), location) {}
-
-bool Status::compare(const Status& other) const {
- return code() == other.code() && location() == other.location();
-}
-
-bool Status::operator==(const Status& other) const {
- return compare(other);
-}
-
-bool Status::operator!=(const Status& other) const {
- return !compare(other);
-}
-
-bool Status::compareCode(const ErrorCodes::Error other) const {
- return code() == other;
-}
-
-bool Status::operator==(const ErrorCodes::Error other) const {
- return compareCode(other);
-}
-
-bool Status::operator!=(const ErrorCodes::Error other) const {
- return !compareCode(other);
-}
+Status::Status(ErrorCodes::Error code, const mongoutils::str::stream& reason)
+ : Status(code, std::string(reason)) {}
std::ostream& operator<<(std::ostream& os, const Status& status) {
return os << status.codeString() << " " << status.reason();
@@ -90,8 +65,6 @@ std::string Status::toString() const {
ss << codeString();
if (!isOK())
ss << ": " << reason();
- if (location() != 0)
- ss << " @ " << location();
return ss.str();
}
diff --git a/src/mongo/base/status.h b/src/mongo/base/status.h
index d8009ecc96e..91c5a5ce26e 100644
--- a/src/mongo/base/status.h
+++ b/src/mongo/base/status.h
@@ -47,8 +47,7 @@ namespace mongo {
*
* A Status uses the standardized error codes -- from file 'error_codes.h' -- to
* determine an error's cause. It further clarifies the error with a textual
- * description. Optionally, a Status may also have an error location number, which
- * should be a unique, grep-able point in the code base (including assert numbers).
+ * description.
*
* Example usage:
*
@@ -60,10 +59,6 @@ namespace mongo {
* *c = a+b;
* return Status::OK();
* }
- *
- * TODO: expand base/error_codes.h to capture common errors in current code
- * TODO: generate base/error_codes.h out of a description file
- * TODO: check 'location' duplicates against assert numbers
*/
class MONGO_WARN_UNUSED_RESULT_CLASS Status {
public:
@@ -71,22 +66,16 @@ public:
static inline Status OK();
/**
- * Builds an error status given the error code, a textual description of what
- * caused the error, and a unique position in the where the error occurred
- * (similar to an assert number).
+ * Builds an error status given the error code and a textual description of what
+ * caused the error.
*
* For OK Statuses prefer using Status::OK(). If code is OK, the remaining arguments are
* ignored.
*/
+ MONGO_COMPILER_COLD_FUNCTION Status(ErrorCodes::Error code, std::string reason);
+ MONGO_COMPILER_COLD_FUNCTION Status(ErrorCodes::Error code, const char* reason);
MONGO_COMPILER_COLD_FUNCTION Status(ErrorCodes::Error code,
- std::string reason,
- int location = 0);
- MONGO_COMPILER_COLD_FUNCTION Status(ErrorCodes::Error code,
- const char* reason,
- int location = 0);
- MONGO_COMPILER_COLD_FUNCTION Status(ErrorCodes::Error code,
- const mongoutils::str::stream& reason,
- int location = 0);
+ const mongoutils::str::stream& reason);
inline Status(const Status& other);
inline Status& operator=(const Status& other);
@@ -97,20 +86,24 @@ public:
inline ~Status();
/**
- * Returns true if 'other's error code and location are equal/different to this
- * instance's. Otherwise returns false.
+ * Only compares codes. Ignores reason strings.
*/
- bool compare(const Status& other) const;
- bool operator==(const Status& other) const;
- bool operator!=(const Status& other) const;
+ bool operator==(const Status& other) const {
+ return code() == other.code();
+ }
+ bool operator!=(const Status& other) const {
+ return !(*this == other);
+ }
/**
- * Returns true if 'other's error code is equal/different to this instance's.
- * Otherwise returns false.
+ * Compares this Status's code with an error code.
*/
- bool compareCode(const ErrorCodes::Error other) const;
- bool operator==(const ErrorCodes::Error other) const;
- bool operator!=(const ErrorCodes::Error other) const;
+ bool operator==(const ErrorCodes::Error other) const {
+ return code() == other;
+ }
+ bool operator!=(const ErrorCodes::Error other) const {
+ return !(*this == other);
+ }
//
// accessors
@@ -124,8 +117,6 @@ public:
inline std::string reason() const;
- inline int location() const;
-
std::string toString() const;
/**
@@ -162,11 +153,10 @@ private:
AtomicUInt32 refs; // reference counter
const ErrorCodes::Error code; // error code
const std::string reason; // description of error cause
- const int location; // unique location of the triggering line in the code
- static ErrorInfo* create(ErrorCodes::Error code, std::string reason, int location);
+ static ErrorInfo* create(ErrorCodes::Error code, std::string reason);
- ErrorInfo(ErrorCodes::Error code, std::string reason, int location);
+ ErrorInfo(ErrorCodes::Error code, std::string reason);
};
ErrorInfo* _error;
diff --git a/src/mongo/base/status_test.cpp b/src/mongo/base/status_test.cpp
index 64af29a0ad5..a8840135624 100644
--- a/src/mongo/base/status_test.cpp
+++ b/src/mongo/base/status_test.cpp
@@ -42,10 +42,9 @@ using mongo::ErrorCodes;
using mongo::Status;
TEST(Basic, Accessors) {
- Status status(ErrorCodes::MaxError, "error", 9999);
+ Status status(ErrorCodes::MaxError, "error");
ASSERT_EQUALS(status.code(), ErrorCodes::MaxError);
ASSERT_EQUALS(status.reason(), "error");
- ASSERT_EQUALS(status.location(), 9999);
}
TEST(Basic, OKIsAValidStatus) {
@@ -55,11 +54,8 @@ TEST(Basic, OKIsAValidStatus) {
TEST(Basic, Compare) {
Status errMax(ErrorCodes::MaxError, "error");
- ASSERT_TRUE(errMax.compare(errMax));
- ASSERT_FALSE(errMax.compare(Status::OK()));
-
- Status errMaxWithLoc(ErrorCodes::MaxError, "error", 9998);
- ASSERT_FALSE(errMaxWithLoc.compare(errMax));
+ ASSERT_EQ(errMax, errMax);
+ ASSERT_NE(errMax, Status::OK());
}
TEST(Cloning, Copy) {
diff --git a/src/mongo/base/status_with.h b/src/mongo/base/status_with.h
index 9287e45d938..05b5731a78a 100644
--- a/src/mongo/base/status_with.h
+++ b/src/mongo/base/status_with.h
@@ -69,18 +69,13 @@ public:
/**
* for the error case
*/
+ MONGO_COMPILER_COLD_FUNCTION StatusWith(ErrorCodes::Error code, std::string reason)
+ : _status(code, std::move(reason)) {}
+ MONGO_COMPILER_COLD_FUNCTION StatusWith(ErrorCodes::Error code, const char* reason)
+ : _status(code, reason) {}
MONGO_COMPILER_COLD_FUNCTION StatusWith(ErrorCodes::Error code,
- std::string reason,
- int location = 0)
- : _status(code, std::move(reason), location) {}
- MONGO_COMPILER_COLD_FUNCTION StatusWith(ErrorCodes::Error code,
- const char* reason,
- int location = 0)
- : _status(code, reason, location) {}
- MONGO_COMPILER_COLD_FUNCTION StatusWith(ErrorCodes::Error code,
- const mongoutils::str::stream& reason,
- int location = 0)
- : _status(code, reason, location) {}
+ const mongoutils::str::stream& reason)
+ : _status(code, reason) {}
/**
* for the error case
diff --git a/src/mongo/db/auth/authorization_manager.cpp b/src/mongo/db/auth/authorization_manager.cpp
index 0e97504b782..f0ebdba5881 100644
--- a/src/mongo/db/auth/authorization_manager.cpp
+++ b/src/mongo/db/auth/authorization_manager.cpp
@@ -416,8 +416,7 @@ Status AuthorizationManager::_initializeUserFromPrivilegeDocument(User* user,
<< userName
<< "\" doesn't match name of provided User \""
<< user->getName().getUser()
- << "\"",
- 0);
+ << "\"");
}
Status status = parser.initializeUserCredentialsFromUserDocument(user, privDoc);
diff --git a/src/mongo/db/auth/generate_action_types.py b/src/mongo/db/auth/generate_action_types.py
index 6d14b0b583d..b712b29666a 100755
--- a/src/mongo/db/auth/generate_action_types.py
+++ b/src/mongo/db/auth/generate_action_types.py
@@ -175,8 +175,7 @@ namespace mongo {
%(fromStringIfStatements)s
return Status(ErrorCodes::FailedToParse,
mongoutils::str::stream() << "Unrecognized action privilege string: "
- << action,
- 0);
+ << action);
}
// Takes an ActionType and returns the string representation
diff --git a/src/mongo/db/auth/role_graph.cpp b/src/mongo/db/auth/role_graph.cpp
index 56ce47f2ecb..b35df15d16d 100644
--- a/src/mongo/db/auth/role_graph.cpp
+++ b/src/mongo/db/auth/role_graph.cpp
@@ -79,8 +79,7 @@ Status RoleGraph::createRole(const RoleName& role) {
if (roleExists(role)) {
return Status(ErrorCodes::DuplicateKey,
mongoutils::str::stream() << "Role: " << role.getFullName()
- << " already exists",
- 0);
+ << " already exists");
}
_createRoleDontCheckIfRoleExists(role);
@@ -102,14 +101,12 @@ Status RoleGraph::deleteRole(const RoleName& role) {
if (!roleExists(role)) {
return Status(ErrorCodes::RoleNotFound,
mongoutils::str::stream() << "Role: " << role.getFullName()
- << " does not exist",
- 0);
+ << " does not exist");
}
if (isBuiltinRole(role)) {
return Status(ErrorCodes::InvalidRoleModification,
mongoutils::str::stream() << "Cannot delete built-in role: "
- << role.getFullName(),
- 0);
+ << role.getFullName());
}
for (std::vector<RoleName>::iterator it = _roleToSubordinates[role].begin();
@@ -195,20 +192,17 @@ Status RoleGraph::removeRoleFromRole(const RoleName& recipient, const RoleName&
if (!roleExists(recipient)) {
return Status(ErrorCodes::RoleNotFound,
mongoutils::str::stream() << "Role: " << recipient.getFullName()
- << " does not exist",
- 0);
+ << " does not exist");
}
if (isBuiltinRole(recipient)) {
return Status(ErrorCodes::InvalidRoleModification,
mongoutils::str::stream() << "Cannot remove roles from built-in role: "
- << role.getFullName(),
- 0);
+ << role.getFullName());
}
if (!roleExists(role)) {
return Status(ErrorCodes::RoleNotFound,
mongoutils::str::stream() << "Role: " << role.getFullName()
- << " does not exist",
- 0);
+ << " does not exist");
}
std::vector<RoleName>::iterator itToRm =
@@ -219,8 +213,7 @@ Status RoleGraph::removeRoleFromRole(const RoleName& recipient, const RoleName&
return Status(ErrorCodes::RolesNotRelated,
mongoutils::str::stream() << recipient.getFullName() << " is not a member"
" of "
- << role.getFullName(),
- 0);
+ << role.getFullName());
}
itToRm = std::find(
@@ -235,14 +228,12 @@ Status RoleGraph::removeAllRolesFromRole(const RoleName& victim) {
if (!roleExists(victim)) {
return Status(ErrorCodes::RoleNotFound,
mongoutils::str::stream() << "Role: " << victim.getFullName()
- << " does not exist",
- 0);
+ << " does not exist");
}
if (isBuiltinRole(victim)) {
return Status(ErrorCodes::InvalidRoleModification,
mongoutils::str::stream() << "Cannot remove roles from built-in role: "
- << victim.getFullName(),
- 0);
+ << victim.getFullName());
}
RoleNameVector& subordinatesOfVictim = _roleToSubordinates[victim];
@@ -264,14 +255,12 @@ Status RoleGraph::addPrivilegeToRole(const RoleName& role, const Privilege& priv
if (!roleExists(role)) {
return Status(ErrorCodes::RoleNotFound,
mongoutils::str::stream() << "Role: " << role.getFullName()
- << " does not exist",
- 0);
+ << " does not exist");
}
if (isBuiltinRole(role)) {
return Status(ErrorCodes::InvalidRoleModification,
mongoutils::str::stream() << "Cannot grant privileges to built-in role: "
- << role.getFullName(),
- 0);
+ << role.getFullName());
}
_addPrivilegeToRoleNoChecks(role, privilegeToAdd);
@@ -291,14 +280,12 @@ Status RoleGraph::addPrivilegesToRole(const RoleName& role,
if (!roleExists(role)) {
return Status(ErrorCodes::RoleNotFound,
mongoutils::str::stream() << "Role: " << role.getFullName()
- << " does not exist",
- 0);
+ << " does not exist");
}
if (isBuiltinRole(role)) {
return Status(ErrorCodes::InvalidRoleModification,
mongoutils::str::stream() << "Cannot grant privileges to built-in role: "
- << role.getFullName(),
- 0);
+ << role.getFullName());
}
for (PrivilegeVector::const_iterator it = privilegesToAdd.begin(); it != privilegesToAdd.end();
@@ -313,8 +300,7 @@ Status RoleGraph::removePrivilegeFromRole(const RoleName& role,
if (!roleExists(role)) {
return Status(ErrorCodes::RoleNotFound,
mongoutils::str::stream() << "Role: " << role.getFullName()
- << " does not exist",
- 0);
+ << " does not exist");
}
if (isBuiltinRole(role)) {
return Status(ErrorCodes::InvalidRoleModification,
@@ -337,8 +323,7 @@ Status RoleGraph::removePrivilegeFromRole(const RoleName& role,
<< " does not contain a privilege on "
<< privilegeToRemove.getResourcePattern().toString()
<< " with actions: "
- << privilegeToRemove.getActions().toString(),
- 0);
+ << privilegeToRemove.getActions().toString());
}
curPrivilege.removeActions(privilegeToRemove.getActions());
@@ -352,8 +337,7 @@ Status RoleGraph::removePrivilegeFromRole(const RoleName& role,
mongoutils::str::stream() << "Role: " << role.getFullName()
<< " does not "
"contain any privileges on "
- << privilegeToRemove.getResourcePattern().toString(),
- 0);
+ << privilegeToRemove.getResourcePattern().toString());
}
Status RoleGraph::removePrivilegesFromRole(const RoleName& role,
@@ -373,8 +357,7 @@ Status RoleGraph::removeAllPrivilegesFromRole(const RoleName& role) {
if (!roleExists(role)) {
return Status(ErrorCodes::RoleNotFound,
mongoutils::str::stream() << "Role: " << role.getFullName()
- << " does not exist",
- 0);
+ << " does not exist");
}
if (isBuiltinRole(role)) {
return Status(ErrorCodes::InvalidRoleModification,
@@ -464,8 +447,7 @@ Status RoleGraph::_recomputePrivilegeDataHelper(const RoleName& startingRole,
if (!roleExists(currentRole)) {
return Status(ErrorCodes::RoleNotFound,
mongoutils::str::stream() << "Role: " << currentRole.getFullName()
- << " does not exist",
- 0);
+ << " does not exist");
}
// Check for cycles
diff --git a/src/mongo/db/auth/user_document_parser.cpp b/src/mongo/db/auth/user_document_parser.cpp
index aca408636a3..edf7e1c4f55 100644
--- a/src/mongo/db/auth/user_document_parser.cpp
+++ b/src/mongo/db/auth/user_document_parser.cpp
@@ -64,22 +64,22 @@ constexpr StringData AUTHENTICATION_RESTRICTIONS_FIELD_NAME = "authenticationRes
constexpr StringData INHERITED_AUTHENTICATION_RESTRICTIONS_FIELD_NAME =
"inheritedAuthenticationRestrictions"_sd;
-inline Status _badValue(const char* reason, int location) {
- return Status(ErrorCodes::BadValue, reason, location);
+inline Status _badValue(const char* reason) {
+ return Status(ErrorCodes::BadValue, reason);
}
-inline Status _badValue(const std::string& reason, int location) {
- return Status(ErrorCodes::BadValue, reason, location);
+inline Status _badValue(const std::string& reason) {
+ return Status(ErrorCodes::BadValue, reason);
}
Status _checkV1RolesArray(const BSONElement& rolesElement) {
if (rolesElement.type() != Array) {
- return _badValue("Role fields must be an array when present in system.users entries", 0);
+ return _badValue("Role fields must be an array when present in system.users entries");
}
for (BSONObjIterator iter(rolesElement.embeddedObject()); iter.more(); iter.next()) {
BSONElement element = *iter;
if (element.type() != String || element.valueStringData().empty()) {
- return _badValue("Roles must be non-empty strings.", 0);
+ return _badValue("Roles must be non-empty strings.");
}
}
return Status::OK();
@@ -210,14 +210,14 @@ Status V1UserDocumentParser::initializeUserRolesFromUserDocument(User* user,
Status _checkV2RolesArray(const BSONElement& rolesElement) {
if (rolesElement.eoo()) {
- return _badValue("User document needs 'roles' field to be provided", 0);
+ return _badValue("User document needs 'roles' field to be provided");
}
if (rolesElement.type() != Array) {
- return _badValue("'roles' field must be an array", 0);
+ return _badValue("'roles' field must be an array");
}
for (BSONObjIterator iter(rolesElement.embeddedObject()); iter.more(); iter.next()) {
if ((*iter).type() != Object) {
- return _badValue("Elements in 'roles' array must objects", 0);
+ return _badValue("Elements in 'roles' array must objects");
}
Status status = V2UserDocumentParser::checkValidRoleObject((*iter).Obj());
if (!status.isOK())
@@ -234,41 +234,39 @@ Status V2UserDocumentParser::checkValidUserDocument(const BSONObj& doc) const {
// Validate the "user" element.
if (userElement.type() != String)
- return _badValue("User document needs 'user' field to be a string", 0);
+ return _badValue("User document needs 'user' field to be a string");
if (userElement.valueStringData().empty())
- return _badValue("User document needs 'user' field to be non-empty", 0);
+ return _badValue("User document needs 'user' field to be non-empty");
// Validate the "db" element
if (userDBElement.type() != String || userDBElement.valueStringData().empty()) {
- return _badValue("User document needs 'db' field to be a non-empty string", 0);
+ return _badValue("User document needs 'db' field to be a non-empty string");
}
StringData userDBStr = userDBElement.valueStringData();
if (!NamespaceString::validDBName(userDBStr, NamespaceString::DollarInDbNameBehavior::Allow) &&
userDBStr != "$external") {
return _badValue(mongoutils::str::stream() << "'" << userDBStr
- << "' is not a valid value for the db field.",
- 0);
+ << "' is not a valid value for the db field.");
}
// Validate the "credentials" element
if (credentialsElement.eoo()) {
- return _badValue("User document needs 'credentials' object", 0);
+ return _badValue("User document needs 'credentials' object");
}
if (credentialsElement.type() != Object) {
- return _badValue("User document needs 'credentials' field to be an object", 0);
+ return _badValue("User document needs 'credentials' field to be an object");
}
BSONObj credentialsObj = credentialsElement.Obj();
if (credentialsObj.isEmpty()) {
- return _badValue("User document needs 'credentials' field to be a non-empty object", 0);
+ return _badValue("User document needs 'credentials' field to be a non-empty object");
}
if (userDBStr == "$external") {
BSONElement externalElement = credentialsObj[MONGODB_EXTERNAL_CREDENTIAL_FIELD_NAME];
if (externalElement.eoo() || externalElement.type() != Bool || !externalElement.Bool()) {
return _badValue(
"User documents for users defined on '$external' must have "
- "'credentials' field set to {external: true}",
- 0);
+ "'credentials' field set to {external: true}");
}
} else {
BSONElement scramElement = credentialsObj[SCRAM_CREDENTIAL_FIELD_NAME];
@@ -278,18 +276,16 @@ Status V2UserDocumentParser::checkValidUserDocument(const BSONObj& doc) const {
if (mongoCRElement.type() != String || mongoCRElement.valueStringData().empty()) {
return _badValue(
"MONGODB-CR credential must to be a non-empty string"
- ", if present",
- 0);
+ ", if present");
}
} else if (!scramElement.eoo()) {
if (scramElement.type() != Object) {
- return _badValue("SCRAM credential must be an object, if present", 0);
+ return _badValue("SCRAM credential must be an object, if present");
}
} else {
return _badValue(
"User document must provide credentials for all "
- "non-external users",
- 0);
+ "non-external users");
}
}
diff --git a/src/mongo/db/catalog/collection.h b/src/mongo/db/catalog/collection.h
index b1d6bf24c3d..467f985de64 100644
--- a/src/mongo/db/catalog/collection.h
+++ b/src/mongo/db/catalog/collection.h
@@ -270,14 +270,14 @@ public:
const std::vector<MultiIndexBlock*>& indexBlocks,
bool enforceQuota) = 0;
- virtual StatusWith<RecordId> updateDocument(OperationContext* opCtx,
- const RecordId& oldLocation,
- const Snapshotted<BSONObj>& oldDoc,
- const BSONObj& newDoc,
- bool enforceQuota,
- bool indexesAffected,
- OpDebug* opDebug,
- OplogUpdateEntryArgs* args) = 0;
+ virtual RecordId updateDocument(OperationContext* opCtx,
+ const RecordId& oldLocation,
+ const Snapshotted<BSONObj>& oldDoc,
+ const BSONObj& newDoc,
+ bool enforceQuota,
+ bool indexesAffected,
+ OpDebug* opDebug,
+ OplogUpdateEntryArgs* args) = 0;
virtual bool updateWithDamagesSupported() const = 0;
@@ -539,14 +539,14 @@ public:
* 'opDebug' Optional argument. When not null, will be used to record operation statistics.
* @return the post update location of the doc (may or may not be the same as oldLocation)
*/
- inline StatusWith<RecordId> updateDocument(OperationContext* const opCtx,
- const RecordId& oldLocation,
- const Snapshotted<BSONObj>& oldDoc,
- const BSONObj& newDoc,
- const bool enforceQuota,
- const bool indexesAffected,
- OpDebug* const opDebug,
- OplogUpdateEntryArgs* const args) {
+ inline RecordId updateDocument(OperationContext* const opCtx,
+ const RecordId& oldLocation,
+ const Snapshotted<BSONObj>& oldDoc,
+ const BSONObj& newDoc,
+ const bool enforceQuota,
+ const bool indexesAffected,
+ OpDebug* const opDebug,
+ OplogUpdateEntryArgs* const args) {
return this->_impl().updateDocument(
opCtx, oldLocation, oldDoc, newDoc, enforceQuota, indexesAffected, opDebug, args);
}
diff --git a/src/mongo/db/catalog/collection_impl.cpp b/src/mongo/db/catalog/collection_impl.cpp
index eb096e7c331..3a58725d9b0 100644
--- a/src/mongo/db/catalog/collection_impl.cpp
+++ b/src/mongo/db/catalog/collection_impl.cpp
@@ -576,25 +576,25 @@ void CollectionImpl::deleteDocument(OperationContext* opCtx,
Counter64 moveCounter;
ServerStatusMetricField<Counter64> moveCounterDisplay("record.moves", &moveCounter);
-StatusWith<RecordId> CollectionImpl::updateDocument(OperationContext* opCtx,
- const RecordId& oldLocation,
- const Snapshotted<BSONObj>& oldDoc,
- const BSONObj& newDoc,
- bool enforceQuota,
- bool indexesAffected,
- OpDebug* opDebug,
- OplogUpdateEntryArgs* args) {
+RecordId CollectionImpl::updateDocument(OperationContext* opCtx,
+ const RecordId& oldLocation,
+ const Snapshotted<BSONObj>& oldDoc,
+ const BSONObj& newDoc,
+ bool enforceQuota,
+ bool indexesAffected,
+ OpDebug* opDebug,
+ OplogUpdateEntryArgs* args) {
{
auto status = checkValidation(opCtx, newDoc);
if (!status.isOK()) {
if (_validationLevel == ValidationLevel::STRICT_V) {
- return status;
+ uassertStatusOK(status);
}
// moderate means we have to check the old doc
auto oldDocStatus = checkValidation(opCtx, oldDoc.value());
if (oldDocStatus.isOK()) {
// transitioning from good -> bad is not ok
- return status;
+ uassertStatusOK(status);
}
// bad -> bad is ok in moderate mode
}
@@ -616,8 +616,7 @@ StatusWith<RecordId> CollectionImpl::updateDocument(OperationContext* opCtx,
BSONElement oldId = oldDoc.value()["_id"];
if (!oldId.eoo() && SimpleBSONElementComparator::kInstance.evaluate(oldId != newDoc["_id"]))
- return StatusWith<RecordId>(
- ErrorCodes::InternalError, "in Collection::updateDocument _id mismatch", 13596);
+ uasserted(13596, "in Collection::updateDocument _id mismatch");
// The MMAPv1 storage engine implements capped collections in a way that does not allow records
// to grow beyond their original size. If MMAPv1 part of a replicaset with storage engines that
@@ -628,11 +627,11 @@ StatusWith<RecordId> CollectionImpl::updateDocument(OperationContext* opCtx,
// all size changes.
const auto oldSize = oldDoc.value().objsize();
if (_recordStore->isCapped() && oldSize != newDoc.objsize())
- return {ErrorCodes::CannotGrowDocumentInCappedNamespace,
- str::stream() << "Cannot change the size of a document in a capped collection: "
- << oldSize
- << " != "
- << newDoc.objsize()};
+ uasserted(ErrorCodes::CannotGrowDocumentInCappedNamespace,
+ str::stream() << "Cannot change the size of a document in a capped collection: "
+ << oldSize
+ << " != "
+ << newDoc.objsize());
// At the end of this step, we will have a map of UpdateTickets, one per index, which
// represent the index updates needed to be done, based on the changes between oldDoc and
@@ -649,16 +648,13 @@ StatusWith<RecordId> CollectionImpl::updateDocument(OperationContext* opCtx,
IndexCatalog::prepareInsertDeleteOptions(opCtx, descriptor, &options);
UpdateTicket* updateTicket = new UpdateTicket();
updateTickets.mutableMap()[descriptor] = updateTicket;
- Status ret = iam->validateUpdate(opCtx,
- oldDoc.value(),
- newDoc,
- oldLocation,
- options,
- updateTicket,
- entry->getFilterExpression());
- if (!ret.isOK()) {
- return StatusWith<RecordId>(ret);
- }
+ uassertStatusOK(iam->validateUpdate(opCtx,
+ oldDoc.value(),
+ newDoc,
+ oldLocation,
+ options,
+ updateTicket,
+ entry->getFilterExpression()));
}
}
@@ -666,11 +662,10 @@ StatusWith<RecordId> CollectionImpl::updateDocument(OperationContext* opCtx,
opCtx, oldLocation, newDoc.objdata(), newDoc.objsize(), _enforceQuota(enforceQuota), this);
if (updateStatus == ErrorCodes::NeedsDocumentMove) {
- return _updateDocumentWithMove(
- opCtx, oldLocation, oldDoc, newDoc, enforceQuota, opDebug, args, sid);
- } else if (!updateStatus.isOK()) {
- return updateStatus;
+ return uassertStatusOK(_updateDocumentWithMove(
+ opCtx, oldLocation, oldDoc, newDoc, enforceQuota, opDebug, args, sid));
}
+ uassertStatusOK(updateStatus);
// Object did not move. We update each index with each respective UpdateTicket.
if (indexesAffected) {
@@ -681,10 +676,8 @@ StatusWith<RecordId> CollectionImpl::updateDocument(OperationContext* opCtx,
int64_t keysInserted;
int64_t keysDeleted;
- Status ret = iam->update(
- opCtx, *updateTickets.mutableMap()[descriptor], &keysInserted, &keysDeleted);
- if (!ret.isOK())
- return StatusWith<RecordId>(ret);
+ uassertStatusOK(iam->update(
+ opCtx, *updateTickets.mutableMap()[descriptor], &keysInserted, &keysDeleted));
if (opDebug) {
opDebug->keysInserted += keysInserted;
opDebug->keysDeleted += keysDeleted;
diff --git a/src/mongo/db/catalog/collection_impl.h b/src/mongo/db/catalog/collection_impl.h
index 1fdfc40d1fa..b9132e26261 100644
--- a/src/mongo/db/catalog/collection_impl.h
+++ b/src/mongo/db/catalog/collection_impl.h
@@ -208,14 +208,14 @@ public:
* 'opDebug' Optional argument. When not null, will be used to record operation statistics.
* @return the post update location of the doc (may or may not be the same as oldLocation)
*/
- StatusWith<RecordId> updateDocument(OperationContext* opCtx,
- const RecordId& oldLocation,
- const Snapshotted<BSONObj>& oldDoc,
- const BSONObj& newDoc,
- bool enforceQuota,
- bool indexesAffected,
- OpDebug* opDebug,
- OplogUpdateEntryArgs* args) final;
+ RecordId updateDocument(OperationContext* opCtx,
+ const RecordId& oldLocation,
+ const Snapshotted<BSONObj>& oldDoc,
+ const BSONObj& newDoc,
+ bool enforceQuota,
+ bool indexesAffected,
+ OpDebug* opDebug,
+ OplogUpdateEntryArgs* args) final;
bool updateWithDamagesSupported() const final;
diff --git a/src/mongo/db/catalog/collection_mock.h b/src/mongo/db/catalog/collection_mock.h
index 38339efb7df..a5bb17349ac 100644
--- a/src/mongo/db/catalog/collection_mock.h
+++ b/src/mongo/db/catalog/collection_mock.h
@@ -167,14 +167,14 @@ public:
std::abort();
}
- StatusWith<RecordId> updateDocument(OperationContext* opCtx,
- const RecordId& oldLocation,
- const Snapshotted<BSONObj>& oldDoc,
- const BSONObj& newDoc,
- bool enforceQuota,
- bool indexesAffected,
- OpDebug* opDebug,
- OplogUpdateEntryArgs* args) {
+ RecordId updateDocument(OperationContext* opCtx,
+ const RecordId& oldLocation,
+ const Snapshotted<BSONObj>& oldDoc,
+ const BSONObj& newDoc,
+ bool enforceQuota,
+ bool indexesAffected,
+ OpDebug* opDebug,
+ OplogUpdateEntryArgs* args) {
std::abort();
}
diff --git a/src/mongo/db/exec/update.cpp b/src/mongo/db/exec/update.cpp
index 42e2bb3bf8f..0788a621ee9 100644
--- a/src/mongo/db/exec/update.cpp
+++ b/src/mongo/db/exec/update.cpp
@@ -87,16 +87,12 @@ Status ensureIdFieldIsFirst(mb::Document* doc) {
return Status::OK();
}
-Status addObjectIDIdField(mb::Document* doc) {
+void addObjectIDIdField(mb::Document* doc) {
const auto idElem = doc->makeElementNewOID(idFieldName);
if (!idElem.ok())
- return {ErrorCodes::BadValue, "Could not create new ObjectId '_id' field.", 17268};
+ uasserted(17268, "Could not create new ObjectId '_id' field.");
- const auto s = doc->root().pushFront(idElem);
- if (!s.isOK())
- return s;
-
- return Status::OK();
+ uassertStatusOK(doc->root().pushFront(idElem));
}
/**
@@ -253,7 +249,7 @@ BSONObj UpdateStage::transformAndUpdate(const Snapshotted<BSONObj>& oldObj, Reco
if (status.code() == ErrorCodes::InvalidIdField) {
// Create ObjectId _id field if we are doing that
if (createIdField) {
- uassertStatusOK(addObjectIDIdField(&_doc));
+ addObjectIDIdField(&_doc);
}
} else {
uassertStatusOK(status);
@@ -324,16 +320,14 @@ BSONObj UpdateStage::transformAndUpdate(const Snapshotted<BSONObj>& oldObj, Reco
args.update = logObj;
args.criteria = idQuery;
args.fromMigrate = request->isFromMigration();
- StatusWith<RecordId> res = _collection->updateDocument(getOpCtx(),
- recordId,
- oldObj,
- newObj,
- true,
- driver->modsAffectIndices(),
- _params.opDebug,
- &args);
- uassertStatusOK(res.getStatus());
- newRecordId = res.getValue();
+ newRecordId = _collection->updateDocument(getOpCtx(),
+ recordId,
+ oldObj,
+ newObj,
+ true,
+ driver->modsAffectIndices(),
+ _params.opDebug,
+ &args);
}
}
@@ -362,15 +356,14 @@ BSONObj UpdateStage::transformAndUpdate(const Snapshotted<BSONObj>& oldObj, Reco
return newObj;
}
-Status UpdateStage::applyUpdateOpsForInsert(OperationContext* opCtx,
- const CanonicalQuery* cq,
- const BSONObj& query,
- UpdateDriver* driver,
- mutablebson::Document* doc,
- bool isInternalRequest,
- const NamespaceString& ns,
- UpdateStats* stats,
- BSONObj* out) {
+BSONObj UpdateStage::applyUpdateOpsForInsert(OperationContext* opCtx,
+ const CanonicalQuery* cq,
+ const BSONObj& query,
+ UpdateDriver* driver,
+ mutablebson::Document* doc,
+ bool isInternalRequest,
+ const NamespaceString& ns,
+ UpdateStats* stats) {
// Since this is an insert (no docs found and upsert:true), we will be logging it
// as an insert in the oplog. We don't need the driver's help to build the
// oplog record, then. We also set the context of the update driver to the INSERT_CONTEXT.
@@ -392,11 +385,7 @@ Status UpdateStage::applyUpdateOpsForInsert(OperationContext* opCtx,
BSONObj original;
if (cq) {
- Status status = driver->populateDocumentWithQueryFields(*cq, immutablePaths, *doc);
- if (!status.isOK()) {
- return status;
- }
-
+ uassertStatusOK(driver->populateDocumentWithQueryFields(*cq, immutablePaths, *doc));
if (driver->isDocReplacement())
stats->fastmodinsert = true;
original = doc->getObject();
@@ -416,17 +405,15 @@ Status UpdateStage::applyUpdateOpsForInsert(OperationContext* opCtx,
Status updateStatus =
driver->update(StringData(), original, doc, validateForStorage, immutablePaths);
if (!updateStatus.isOK()) {
- return Status(updateStatus.code(), updateStatus.reason(), 16836);
+ uasserted(16836, updateStatus.reason());
}
// Ensure _id exists and is first
auto idAndFirstStatus = ensureIdFieldIsFirst(doc);
if (idAndFirstStatus.code() == ErrorCodes::InvalidIdField) { // _id field is missing
- idAndFirstStatus = addObjectIDIdField(doc);
- }
-
- if (!idAndFirstStatus.isOK()) {
- return idAndFirstStatus;
+ addObjectIDIdField(doc);
+ } else {
+ uassertStatusOK(idAndFirstStatus);
}
// Validate that the object replacement or modifiers resulted in a document
@@ -441,13 +428,11 @@ Status UpdateStage::applyUpdateOpsForInsert(OperationContext* opCtx,
BSONObj newObj = doc->getObject();
if (newObj.objsize() > BSONObjMaxUserSize) {
- return Status(ErrorCodes::InvalidBSON,
- str::stream() << "Document to upsert is larger than " << BSONObjMaxUserSize,
- 17420);
+ uasserted(17420,
+ str::stream() << "Document to upsert is larger than " << BSONObjMaxUserSize);
}
- *out = newObj;
- return Status::OK();
+ return newObj;
}
void UpdateStage::doInsert() {
@@ -459,16 +444,14 @@ void UpdateStage::doInsert() {
// Reset the document we will be writing to.
_doc.reset();
- BSONObj newObj;
- uassertStatusOK(applyUpdateOpsForInsert(getOpCtx(),
- _params.canonicalQuery,
- request->getQuery(),
- _params.driver,
- &_doc,
- isInternalRequest,
- request->getNamespaceString(),
- &_specificStats,
- &newObj));
+ BSONObj newObj = applyUpdateOpsForInsert(getOpCtx(),
+ _params.canonicalQuery,
+ request->getQuery(),
+ _params.driver,
+ &_doc,
+ isInternalRequest,
+ request->getNamespaceString(),
+ &_specificStats);
_specificStats.objInserted = newObj;
@@ -722,7 +705,7 @@ PlanStage::StageState UpdateStage::doWork(WorkingSetID* out) {
return status;
}
-Status UpdateStage::restoreUpdateState() {
+void UpdateStage::doRestoreState() {
const UpdateRequest& request = *_params.request;
const NamespaceString& nsString(request.getNamespaceString());
@@ -731,9 +714,9 @@ Status UpdateStage::restoreUpdateState() {
!repl::getGlobalReplicationCoordinator()->canAcceptWritesFor(getOpCtx(), nsString);
if (userInitiatedWritesAndNotPrimary) {
- return Status(ErrorCodes::PrimarySteppedDown,
- str::stream() << "Demoted from primary while performing update on "
- << nsString.ns());
+ uasserted(ErrorCodes::PrimarySteppedDown,
+ str::stream() << "Demoted from primary while performing update on "
+ << nsString.ns());
}
if (request.getLifecycle()) {
@@ -741,19 +724,11 @@ Status UpdateStage::restoreUpdateState() {
lifecycle->setCollection(_collection);
if (!lifecycle->canContinue()) {
- return Status(ErrorCodes::IllegalOperation,
- "Update aborted due to invalid state transitions after yield.",
- 17270);
+ uasserted(17270, "Update aborted due to invalid state transitions after yield.");
}
_params.driver->refreshIndexKeys(lifecycle->getIndexKeys(getOpCtx()));
}
-
- return Status::OK();
-}
-
-void UpdateStage::doRestoreState() {
- uassertStatusOK(restoreUpdateState());
}
unique_ptr<PlanStageStats> UpdateStage::getStats() {
diff --git a/src/mongo/db/exec/update.h b/src/mongo/db/exec/update.h
index fa866f87606..f5dccd1c7e6 100644
--- a/src/mongo/db/exec/update.h
+++ b/src/mongo/db/exec/update.h
@@ -132,17 +132,16 @@ public:
*
* Fills out whether or not this is a fastmodinsert in 'stats'.
*
- * Returns the document to insert in *out.
+ * Returns the document to insert.
*/
- static Status applyUpdateOpsForInsert(OperationContext* opCtx,
- const CanonicalQuery* cq,
- const BSONObj& query,
- UpdateDriver* driver,
- mutablebson::Document* doc,
- bool isInternalRequest,
- const NamespaceString& ns,
- UpdateStats* stats,
- BSONObj* out);
+ static BSONObj applyUpdateOpsForInsert(OperationContext* opCtx,
+ const CanonicalQuery* cq,
+ const BSONObj& query,
+ UpdateDriver* driver,
+ mutablebson::Document* doc,
+ bool isInternalRequest,
+ const NamespaceString& ns,
+ UpdateStats* stats);
private:
/**
@@ -171,11 +170,6 @@ private:
bool needInsert();
/**
- * Helper for restoring the state of this update.
- */
- Status restoreUpdateState();
-
- /**
* Stores 'idToRetry' in '_idRetrying' so the update can be retried during the next call to
* work(). Always returns NEED_YIELD and sets 'out' to WorkingSet::INVALID_ID.
*/
diff --git a/src/mongo/db/pipeline/parsed_add_fields.cpp b/src/mongo/db/pipeline/parsed_add_fields.cpp
index 0cbe513a720..bfd5774c3ba 100644
--- a/src/mongo/db/pipeline/parsed_add_fields.cpp
+++ b/src/mongo/db/pipeline/parsed_add_fields.cpp
@@ -41,11 +41,7 @@ namespace parsed_aggregation_projection {
std::unique_ptr<ParsedAddFields> ParsedAddFields::create(
const boost::intrusive_ptr<ExpressionContext>& expCtx, const BSONObj& spec) {
// Verify that we don't have conflicting field paths, etc.
- Status status = ProjectionSpecValidator::validate(spec);
- if (!status.isOK()) {
- uasserted(status.location(),
- str::stream() << "Invalid $addFields specification: " << status.reason());
- }
+ ProjectionSpecValidator::uassertValid(spec, "$addFields");
std::unique_ptr<ParsedAddFields> parsedAddFields = stdx::make_unique<ParsedAddFields>(expCtx);
// Actually parse the specification.
diff --git a/src/mongo/db/pipeline/parsed_aggregation_projection.cpp b/src/mongo/db/pipeline/parsed_aggregation_projection.cpp
index cfa7d6da39c..1588e796970 100644
--- a/src/mongo/db/pipeline/parsed_aggregation_projection.cpp
+++ b/src/mongo/db/pipeline/parsed_aggregation_projection.cpp
@@ -53,57 +53,56 @@ using TransformerType =
// ProjectionSpecValidator
//
-Status ProjectionSpecValidator::validate(const BSONObj& spec) {
- return ProjectionSpecValidator(spec).validate();
+void ProjectionSpecValidator::uassertValid(const BSONObj& spec, StringData stageName) {
+ try {
+ ProjectionSpecValidator(spec).validate();
+ } catch (DBException& ex) {
+ ex.addContext("Invalid " + stageName.toString());
+ throw;
+ }
}
-Status ProjectionSpecValidator::ensurePathDoesNotConflictOrThrow(StringData path) {
+void ProjectionSpecValidator::ensurePathDoesNotConflictOrThrow(StringData path) {
for (auto&& seenPath : _seenPaths) {
if ((path == seenPath) || (expression::isPathPrefixOf(path, seenPath)) ||
(expression::isPathPrefixOf(seenPath, path))) {
- return Status(ErrorCodes::FailedToParse,
- str::stream() << "specification contains two conflicting paths. "
- "Cannot specify both '"
- << path
- << "' and '"
- << seenPath
- << "': "
- << _rawObj.toString(),
- 40176);
+ uasserted(40176,
+ str::stream() << "specification contains two conflicting paths. "
+ "Cannot specify both '"
+ << path
+ << "' and '"
+ << seenPath
+ << "': "
+ << _rawObj.toString());
}
}
_seenPaths.emplace_back(path.toString());
- return Status::OK();
}
-Status ProjectionSpecValidator::validate() {
+void ProjectionSpecValidator::validate() {
if (_rawObj.isEmpty()) {
- return Status(
- ErrorCodes::FailedToParse, "specification must have at least one field", 40177);
+ uasserted(40177, "specification must have at least one field");
}
for (auto&& elem : _rawObj) {
- Status status = parseElement(elem, FieldPath(elem.fieldName()));
- if (!status.isOK())
- return status;
+ parseElement(elem, FieldPath(elem.fieldName()));
}
- return Status::OK();
}
-Status ProjectionSpecValidator::parseElement(const BSONElement& elem, const FieldPath& pathToElem) {
+void ProjectionSpecValidator::parseElement(const BSONElement& elem, const FieldPath& pathToElem) {
if (elem.type() == BSONType::Object) {
- return parseNestedObject(elem.Obj(), pathToElem);
+ parseNestedObject(elem.Obj(), pathToElem);
+ } else {
+ ensurePathDoesNotConflictOrThrow(pathToElem.fullPath());
}
- return ensurePathDoesNotConflictOrThrow(pathToElem.fullPath());
}
-Status ProjectionSpecValidator::parseNestedObject(const BSONObj& thisLevelSpec,
- const FieldPath& prefix) {
+void ProjectionSpecValidator::parseNestedObject(const BSONObj& thisLevelSpec,
+ const FieldPath& prefix) {
if (thisLevelSpec.isEmpty()) {
- return Status(ErrorCodes::FailedToParse,
- str::stream()
- << "an empty object is not a valid value. Found empty object at path "
- << prefix.fullPath(),
- 40180);
+ uasserted(
+ 40180,
+ str::stream() << "an empty object is not a valid value. Found empty object at path "
+ << prefix.fullPath());
}
for (auto&& elem : thisLevelSpec) {
auto fieldName = elem.fieldNameStringData();
@@ -112,34 +111,26 @@ Status ProjectionSpecValidator::parseNestedObject(const BSONObj& thisLevelSpec,
// into an Expression later, but for now, just track that the prefix has been
// specified and skip it.
if (thisLevelSpec.nFields() != 1) {
- return Status(ErrorCodes::FailedToParse,
- str::stream() << "an expression specification must contain exactly "
- "one field, the name of the expression. Found "
- << thisLevelSpec.nFields()
- << " fields in "
- << thisLevelSpec.toString()
- << ", while parsing object "
- << _rawObj.toString(),
- 40181);
+ uasserted(40181,
+ str::stream() << "an expression specification must contain exactly "
+ "one field, the name of the expression. Found "
+ << thisLevelSpec.nFields()
+ << " fields in "
+ << thisLevelSpec.toString()
+ << ", while parsing object "
+ << _rawObj.toString());
}
- Status status = ensurePathDoesNotConflictOrThrow(prefix.fullPath());
- if (!status.isOK())
- return status;
+ ensurePathDoesNotConflictOrThrow(prefix.fullPath());
continue;
}
if (fieldName.find('.') != std::string::npos) {
- return Status(ErrorCodes::FailedToParse,
- str::stream() << "cannot use dotted field name '" << fieldName
- << "' in a sub object: "
- << _rawObj.toString(),
- 40183);
+ uasserted(40183,
+ str::stream() << "cannot use dotted field name '" << fieldName
+ << "' in a sub object: "
+ << _rawObj.toString());
}
- Status status =
- parseElement(elem, FieldPath::getFullyQualifiedPath(prefix.fullPath(), fieldName));
- if (!status.isOK())
- return status;
+ parseElement(elem, FieldPath::getFullyQualifiedPath(prefix.fullPath(), fieldName));
}
- return Status::OK();
}
namespace {
@@ -279,11 +270,7 @@ std::unique_ptr<ParsedAggregationProjection> ParsedAggregationProjection::create
// Check that the specification was valid. Status returned is unspecific because validate()
// is used by the $addFields stage as well as $project.
// If there was an error, uassert with a $project-specific message.
- Status status = ProjectionSpecValidator::validate(spec);
- if (!status.isOK()) {
- uasserted(status.location(),
- str::stream() << "Invalid $project specification: " << status.reason());
- }
+ ProjectionSpecValidator::uassertValid(spec, "$project");
// Check for any conflicting specifications, and determine the type of the projection.
auto projectionType = ProjectTypeParser::parse(spec);
diff --git a/src/mongo/db/pipeline/parsed_aggregation_projection.h b/src/mongo/db/pipeline/parsed_aggregation_projection.h
index 721c086f6e1..126254ce908 100644
--- a/src/mongo/db/pipeline/parsed_aggregation_projection.h
+++ b/src/mongo/db/pipeline/parsed_aggregation_projection.h
@@ -53,10 +53,10 @@ namespace parsed_aggregation_projection {
class ProjectionSpecValidator {
public:
/**
- * Returns a Status: either a Status::OK() if the specification is valid for a projection, or a
- * non-OK Status, error number, and message with why not.
+ * Throws if the specification is not valid for a projection. The stageName is used to provide a
+ * more helpful error message.
*/
- static Status validate(const BSONObj& spec);
+ static void uassertValid(const BSONObj& spec, StringData stageName);
private:
ProjectionSpecValidator(const BSONObj& spec) : _rawObj(spec) {}
@@ -67,12 +67,12 @@ private:
* For example, a user is not allowed to specify {'a': 1, 'a.b': 1}, or some similar conflicting
* paths.
*/
- Status ensurePathDoesNotConflictOrThrow(StringData path);
+ void ensurePathDoesNotConflictOrThrow(StringData path);
/**
- * Returns the relevant error if an invalid projection specification is detected.
+ * Throws if an invalid projection specification is detected.
*/
- Status validate();
+ void validate();
/**
* Parses a single BSONElement. 'pathToElem' should include the field name of 'elem'.
@@ -80,19 +80,18 @@ private:
* Delegates to parseSubObject() if 'elem' is an object. Otherwise adds the full path to 'elem'
* to '_seenPaths'.
*
- * Calls ensurePathDoesNotConflictOrThrow with the path to this element, which sets the _status
- * appropriately for conflicting path specifications.
+ * Calls ensurePathDoesNotConflictOrThrow with the path to this element, throws on conflicting
+ * path specifications.
*/
- Status parseElement(const BSONElement& elem, const FieldPath& pathToElem);
+ void parseElement(const BSONElement& elem, const FieldPath& pathToElem);
/**
* Traverses 'thisLevelSpec', parsing each element in turn.
*
- * Sets _status appropriately if any paths conflict with each other or existing paths,
- * 'thisLevelSpec' contains a dotted path, or if 'thisLevelSpec' represents an invalid
- * expression.
+ * Throws if any paths conflict with each other or existing paths, 'thisLevelSpec' contains a
+ * dotted path, or if 'thisLevelSpec' represents an invalid expression.
*/
- Status parseNestedObject(const BSONObj& thisLevelSpec, const FieldPath& prefix);
+ void parseNestedObject(const BSONObj& thisLevelSpec, const FieldPath& prefix);
// The original object. Used to generate more helpful error messages.
const BSONObj& _rawObj;
diff --git a/src/mongo/db/pipeline/pipeline.cpp b/src/mongo/db/pipeline/pipeline.cpp
index 8b84fe36bff..5c2ce92237f 100644
--- a/src/mongo/db/pipeline/pipeline.cpp
+++ b/src/mongo/db/pipeline/pipeline.cpp
@@ -115,24 +115,28 @@ StatusWith<std::unique_ptr<Pipeline, Pipeline::Deleter>> Pipeline::createTopLeve
const bool isFacetPipeline) {
std::unique_ptr<Pipeline, Pipeline::Deleter> pipeline(new Pipeline(std::move(stages), expCtx),
Pipeline::Deleter(expCtx->opCtx));
- auto status =
- (isFacetPipeline ? pipeline->validateFacetPipeline() : pipeline->validatePipeline());
- if (!status.isOK()) {
- return status;
+ try {
+ if (isFacetPipeline) {
+ pipeline->validateFacetPipeline();
+ } else {
+ pipeline->validatePipeline();
+ }
+ } catch (const DBException& ex) {
+ return ex.toStatus();
}
pipeline->stitch();
return std::move(pipeline);
}
-Status Pipeline::validatePipeline() const {
+void Pipeline::validatePipeline() const {
// Verify that the specified namespace is valid for the initial stage of this pipeline.
const NamespaceString& nss = pCtx->ns;
if (_sources.empty()) {
if (nss.isCollectionlessAggregateNS()) {
- return {ErrorCodes::InvalidNamespace,
- "{aggregate: 1} is not valid for an empty pipeline."};
+ uasserted(ErrorCodes::InvalidNamespace,
+ "{aggregate: 1} is not valid for an empty pipeline.");
}
} else if (!dynamic_cast<DocumentSourceMergeCursors*>(_sources.front().get())) {
// The $mergeCursors stage can take {aggregate: 1} or a normal namespace. Aside from this,
@@ -141,35 +145,34 @@ Status Pipeline::validatePipeline() const {
if (nss.isCollectionlessAggregateNS() &&
!firstStage->constraints().isIndependentOfAnyCollection) {
- return {ErrorCodes::InvalidNamespace,
- str::stream() << "{aggregate: 1} is not valid for '"
- << firstStage->getSourceName()
- << "'; a collection is required."};
+ uasserted(ErrorCodes::InvalidNamespace,
+ str::stream() << "{aggregate: 1} is not valid for '"
+ << firstStage->getSourceName()
+ << "'; a collection is required.");
}
if (!nss.isCollectionlessAggregateNS() &&
firstStage->constraints().isIndependentOfAnyCollection) {
- return {ErrorCodes::InvalidNamespace,
- str::stream() << "'" << firstStage->getSourceName()
- << "' can only be run with {aggregate: 1}"};
+ uasserted(ErrorCodes::InvalidNamespace,
+ str::stream() << "'" << firstStage->getSourceName()
+ << "' can only be run with {aggregate: 1}");
}
}
// Verify that each stage is in a legal position within the pipeline.
- return ensureAllStagesAreInLegalPositions();
+ ensureAllStagesAreInLegalPositions();
}
-Status Pipeline::validateFacetPipeline() const {
+void Pipeline::validateFacetPipeline() const {
if (_sources.empty()) {
- return {ErrorCodes::BadValue, "sub-pipeline in $facet stage cannot be empty"};
+ uasserted(ErrorCodes::BadValue, "sub-pipeline in $facet stage cannot be empty");
}
for (auto&& stage : _sources) {
auto stageConstraints = stage->constraints();
if (!stageConstraints.isAllowedInsideFacetStage) {
- return {ErrorCodes::BadValue,
- str::stream() << stage->getSourceName()
- << " is not allowed to be used within a $facet stage",
- 40550};
+ uasserted(40600,
+ str::stream() << stage->getSourceName()
+ << " is not allowed to be used within a $facet stage");
}
// We expect a stage within a $facet stage to have these properties.
invariant(stageConstraints.requiresInputDocSource);
@@ -180,35 +183,30 @@ Status Pipeline::validateFacetPipeline() const {
// Facet pipelines cannot have any stages which are initial sources. We've already validated the
// first stage, and the 'ensureAllStagesAreInLegalPositions' method checks that there are no
// initial sources in positions 1...N, so we can just return its result directly.
- return ensureAllStagesAreInLegalPositions();
+ ensureAllStagesAreInLegalPositions();
}
-Status Pipeline::ensureAllStagesAreInLegalPositions() const {
+void Pipeline::ensureAllStagesAreInLegalPositions() const {
size_t i = 0;
for (auto&& stage : _sources) {
if (stage->constraints().requiredPosition == PositionRequirement::kFirst && i != 0) {
- return {ErrorCodes::BadValue,
- str::stream() << stage->getSourceName()
- << " is only valid as the first stage in a pipeline.",
- 40549};
+ uasserted(40602,
+ str::stream() << stage->getSourceName()
+ << " is only valid as the first stage in a pipeline.");
}
auto matchStage = dynamic_cast<DocumentSourceMatch*>(stage.get());
if (i != 0 && matchStage && matchStage->isTextQuery()) {
- return {ErrorCodes::BadValue,
- "$match with $text is only allowed as the first pipeline stage",
- 17313};
+ uasserted(17313, "$match with $text is only allowed as the first pipeline stage");
}
if (stage->constraints().requiredPosition == PositionRequirement::kLast &&
i != _sources.size() - 1) {
- return {ErrorCodes::BadValue,
- str::stream() << stage->getSourceName()
- << " can only be the final stage in the pipeline",
- 40551};
+ uasserted(40601,
+ str::stream() << stage->getSourceName()
+ << " can only be the final stage in the pipeline");
}
++i;
}
- return Status::OK();
}
void Pipeline::optimizePipeline() {
diff --git a/src/mongo/db/pipeline/pipeline.h b/src/mongo/db/pipeline/pipeline.h
index ed19d44ae2b..6f46bf75476 100644
--- a/src/mongo/db/pipeline/pipeline.h
+++ b/src/mongo/db/pipeline/pipeline.h
@@ -320,17 +320,17 @@ private:
void unstitch();
/**
- * Returns a non-OK status if the pipeline fails any of a set of semantic checks. For example,
- * if an $out stage is present then it must come last in the pipeline, while initial stages such
- * as $indexStats must be at the start.
+ * Throws if the pipeline fails any of a set of semantic checks. For example, if an $out stage
+ * is present then it must come last in the pipeline, while initial stages such as $indexStats
+ * must be at the start.
*/
- Status validatePipeline() const;
+ void validatePipeline() const;
/**
- * Returns a non-OK status if the $facet pipeline fails any of a set of semantic checks. For
- * example, the pipeline cannot be empty and may not contain any initial stages.
+ * Throws if the $facet pipeline fails any of a set of semantic checks. For example, the
+ * pipeline cannot be empty and may not contain any initial stages.
*/
- Status validateFacetPipeline() const;
+ void validateFacetPipeline() const;
/**
* Helper method which validates that each stage in pipeline is in a legal position. For
@@ -338,7 +338,7 @@ private:
* start. Note that this method accepts an initial source as the first stage, which is illegal
* for $facet pipelines.
*/
- Status ensureAllStagesAreInLegalPositions() const;
+ void ensureAllStagesAreInLegalPositions() const;
SourceContainer _sources;
diff --git a/src/mongo/db/pipeline/pipeline_test.cpp b/src/mongo/db/pipeline/pipeline_test.cpp
index fd407964a02..ac54c766727 100644
--- a/src/mongo/db/pipeline/pipeline_test.cpp
+++ b/src/mongo/db/pipeline/pipeline_test.cpp
@@ -1496,8 +1496,7 @@ TEST_F(PipelineInitialSourceNSTest, ChangeStreamIsNotValidIfNotFirstStage) {
setMockReplicationCoordinatorOnOpCtx(ctx->opCtx);
ctx->ns = NamespaceString("a.collection");
auto parseStatus = Pipeline::parse(rawPipeline, ctx).getStatus();
- ASSERT_EQ(parseStatus, ErrorCodes::BadValue);
- ASSERT_EQ(parseStatus.location(), 40549);
+ ASSERT_EQ(parseStatus, ErrorCodes::fromInt(40602));
}
TEST_F(PipelineInitialSourceNSTest, ChangeStreamIsNotValidIfNotFirstStageInFacet) {
@@ -1507,8 +1506,7 @@ TEST_F(PipelineInitialSourceNSTest, ChangeStreamIsNotValidIfNotFirstStageInFacet
setMockReplicationCoordinatorOnOpCtx(ctx->opCtx);
ctx->ns = NamespaceString("a.collection");
auto parseStatus = Pipeline::parseFacetPipeline(rawPipeline, ctx).getStatus();
- ASSERT_EQ(parseStatus, ErrorCodes::BadValue);
- ASSERT_EQ(parseStatus.location(), 40550);
+ ASSERT_EQ(parseStatus, ErrorCodes::fromInt(40600));
ASSERT(std::string::npos != parseStatus.reason().find("$changeStream"));
}
diff --git a/src/mongo/db/repl/rs_rollback.cpp b/src/mongo/db/repl/rs_rollback.cpp
index d83aabdf0fb..8adbe7de16c 100644
--- a/src/mongo/db/repl/rs_rollback.cpp
+++ b/src/mongo/db/repl/rs_rollback.cpp
@@ -1338,8 +1338,7 @@ Status _syncRollback(OperationContext* opCtx,
str::stream()
<< "need to rollback, but unable to determine common point between"
" local and remote oplog: "
- << e.what(),
- 18752);
+ << e.what());
}
log() << "Rollback common point is " << how.commonPoint;
@@ -1350,7 +1349,7 @@ Status _syncRollback(OperationContext* opCtx,
});
syncFixUp(opCtx, how, rollbackSource, replCoord, replicationProcess);
} catch (const RSFatalException& e) {
- return Status(ErrorCodes::UnrecoverableRollbackError, e.what(), 18753);
+ return Status(ErrorCodes::UnrecoverableRollbackError, e.what());
}
if (MONGO_FAIL_POINT(rollbackHangBeforeFinish)) {
diff --git a/src/mongo/db/repl/rs_rollback_no_uuid.cpp b/src/mongo/db/repl/rs_rollback_no_uuid.cpp
index 69975909f57..ca9d4e6a2c0 100644
--- a/src/mongo/db/repl/rs_rollback_no_uuid.cpp
+++ b/src/mongo/db/repl/rs_rollback_no_uuid.cpp
@@ -200,8 +200,7 @@ Status rollback_internal_no_uuid::updateFixUpInfoFromLocalOplogEntry(FixUpInfo&
if (cmd == NULL) {
severe() << "Rollback no such command " << first.fieldName();
return Status(ErrorCodes::UnrecoverableRollbackError,
- str::stream() << "Rollback no such command " << first.fieldName(),
- 18751);
+ str::stream() << "Rollback no such command " << first.fieldName());
}
if (cmdname == "create") {
// Create collection operation
@@ -914,8 +913,7 @@ Status _syncRollback(OperationContext* opCtx,
str::stream()
<< "need to rollback, but unable to determine common point between"
" local and remote oplog: "
- << e.what(),
- 18752);
+ << e.what());
}
log() << "Rollback common point is " << how.commonPoint;
@@ -926,7 +924,7 @@ Status _syncRollback(OperationContext* opCtx,
});
syncFixUp(opCtx, how, rollbackSource, replCoord, replicationProcess);
} catch (const RSFatalException& e) {
- return Status(ErrorCodes::UnrecoverableRollbackError, e.what(), 18753);
+ return Status(ErrorCodes::UnrecoverableRollbackError, e.what());
}
if (MONGO_FAIL_POINT(rollbackHangBeforeFinish)) {
diff --git a/src/mongo/db/repl/rs_rollback_no_uuid_test.cpp b/src/mongo/db/repl/rs_rollback_no_uuid_test.cpp
index 57e2ca10c9f..8107507d487 100644
--- a/src/mongo/db/repl/rs_rollback_no_uuid_test.cpp
+++ b/src/mongo/db/repl/rs_rollback_no_uuid_test.cpp
@@ -159,7 +159,7 @@ TEST_F(RSRollbackTest, InconsistentMinValid) {
_coordinator,
_replicationProcess.get());
ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, status.code());
- ASSERT_EQUALS(18752, status.location());
+ ASSERT_STRING_CONTAINS(status.reason(), "unable to determine common point");
}
TEST_F(RSRollbackTest, OplogStartMissing) {
@@ -189,7 +189,7 @@ TEST_F(RSRollbackTest, NoRemoteOpLog) {
_coordinator,
_replicationProcess.get());
ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, status.code());
- ASSERT_EQUALS(18752, status.location());
+ ASSERT_STRING_CONTAINS(status.reason(), "unable to determine common point");
}
TEST_F(RSRollbackTest, RemoteGetRollbackIdThrows) {
@@ -407,7 +407,7 @@ TEST_F(RSRollbackTest, RollbackInsertDocumentWithNoId) {
_replicationProcess.get());
stopCapturingLogMessages();
ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, status.code());
- ASSERT_EQUALS(18752, status.location());
+ ASSERT_STRING_CONTAINS(status.reason(), "unable to determine common point");
ASSERT_EQUALS(1, countLogLinesContaining("Cannot roll back op with no _id. ns: test.t,"));
ASSERT_FALSE(rollbackSource.called);
}
@@ -580,7 +580,7 @@ TEST_F(RSRollbackTest, RollbackInsertSystemIndexesMissingNamespace) {
_replicationProcess.get());
stopCapturingLogMessages();
ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, status.code());
- ASSERT_EQUALS(18752, status.location());
+ ASSERT_STRING_CONTAINS(status.reason(), "unable to determine common point");
ASSERT_EQUALS(
1, countLogLinesContaining("Missing collection namespace in system.indexes operation,"));
ASSERT_FALSE(rollbackSource.called);
@@ -628,7 +628,7 @@ TEST_F(RSRollbackTest, RollbackCreateIndexCommandInvalidNamespace) {
_replicationProcess.get());
stopCapturingLogMessages();
ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, status.code());
- ASSERT_EQUALS(18752, status.location());
+ ASSERT_STRING_CONTAINS(status.reason(), "unable to determine common point");
ASSERT_EQUALS(
1, countLogLinesContaining("Invalid collection namespace in createIndexes operation,"));
ASSERT_FALSE(rollbackSource.called);
@@ -815,7 +815,7 @@ TEST_F(RSRollbackTest, RollbackInsertSystemIndexesCommandInvalidNamespace) {
_replicationProcess.get());
stopCapturingLogMessages();
ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, status.code());
- ASSERT_EQUALS(18752, status.location());
+ ASSERT_STRING_CONTAINS(status.reason(), "unable to determine common point");
ASSERT_EQUALS(
1, countLogLinesContaining("Invalid collection namespace in createIndexes operation,"));
ASSERT_FALSE(rollbackSource.called);
@@ -861,7 +861,7 @@ TEST_F(RSRollbackTest, RollbackCreateIndexCommandMissingIndexName) {
_replicationProcess.get());
stopCapturingLogMessages();
ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, status.code());
- ASSERT_EQUALS(18752, status.location());
+ ASSERT_STRING_CONTAINS(status.reason(), "unable to determine common point");
ASSERT_EQUALS(1, countLogLinesContaining("Missing index name in createIndexes operation,"));
ASSERT_FALSE(rollbackSource.called);
}
@@ -897,7 +897,7 @@ TEST_F(RSRollbackTest, RollbackUnknownCommand) {
_coordinator,
_replicationProcess.get());
ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, status.code());
- ASSERT_EQUALS(18751, status.location());
+ ASSERT_STRING_CONTAINS(status.reason(), "Rollback no such command");
}
TEST_F(RSRollbackTest, RollbackDropCollectionCommand) {
@@ -1229,7 +1229,7 @@ TEST_F(RSRollbackTest, RollbackCollectionModificationCommandInvalidCollectionOpt
_coordinator,
_replicationProcess.get());
ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, status.code());
- ASSERT_EQUALS(18753, status.location());
+ ASSERT_STRING_CONTAINS(status.reason(), "Failed to parse options");
}
TEST(RSRollbackTest, LocalEntryWithoutNsIsFatal) {
@@ -1285,12 +1285,13 @@ TEST_F(RSRollbackTest, RollbackReturnsImmediatelyOnFailureToTransitionToRollback
ASSERT_EQUALS(MemberState(MemberState::RS_SECONDARY), _coordinator->getMemberState());
}
-DEATH_TEST_F(RSRollbackTest,
- RollbackUnrecoverableRollbackErrorTriggersFatalAssertion,
- "Unable to complete rollback. A full resync may be needed: "
- "UnrecoverableRollbackError: need to rollback, but unable to determine common point "
- "between local and remote oplog: InvalidSyncSource: remote oplog empty or unreadable "
- "@ 18752") {
+DEATH_TEST_F(
+ RSRollbackTest,
+ RollbackUnrecoverableRollbackErrorTriggersFatalAssertion,
+ "Unable to complete rollback. A full resync may be needed: "
+ "UnrecoverableRollbackError: need to rollback, but unable to determine common point "
+ "between local and remote oplog: InvalidSyncSource: remote oplog empty or unreadable") {
+
// rollback() should abort on getting UnrecoverableRollbackError from syncRollback(). An empty
// local oplog will make syncRollback() return the intended error.
OplogInterfaceMock localOplogWithSingleOplogEntry({makeNoopOplogEntryAndRecordId(Seconds(1))});
diff --git a/src/mongo/db/repl/rs_rollback_test.cpp b/src/mongo/db/repl/rs_rollback_test.cpp
index c2a67fe5c4a..99f18f723ea 100644
--- a/src/mongo/db/repl/rs_rollback_test.cpp
+++ b/src/mongo/db/repl/rs_rollback_test.cpp
@@ -248,7 +248,7 @@ TEST_F(RSRollbackTest, InconsistentMinValid) {
_coordinator,
_replicationProcess.get());
ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, status.code());
- ASSERT_EQUALS(18752, status.location());
+ ASSERT_STRING_CONTAINS(status.reason(), "unable to determine common point");
}
TEST_F(RSRollbackTest, OplogStartMissing) {
@@ -278,7 +278,7 @@ TEST_F(RSRollbackTest, NoRemoteOpLog) {
_coordinator,
_replicationProcess.get());
ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, status.code());
- ASSERT_EQUALS(18752, status.location());
+ ASSERT_STRING_CONTAINS(status.reason(), "unable to determine common point");
}
TEST_F(RSRollbackTest, RemoteGetRollbackIdThrows) {
@@ -514,7 +514,7 @@ TEST_F(RSRollbackTest, RollbackInsertDocumentWithNoId) {
_replicationProcess.get());
stopCapturingLogMessages();
ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, status.code());
- ASSERT_EQUALS(18752, status.location());
+ ASSERT_STRING_CONTAINS(status.reason(), "unable to determine common point");
ASSERT_EQUALS(1, countLogLinesContaining("Cannot roll back op with no _id. ns: test.t,"));
ASSERT_FALSE(rollbackSource.called);
}
@@ -832,7 +832,7 @@ TEST_F(RSRollbackTest, RollbackCreateIndexCommandMissingIndexName) {
_replicationProcess.get());
stopCapturingLogMessages();
ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, status.code());
- ASSERT_EQUALS(18752, status.location());
+ ASSERT_STRING_CONTAINS(status.reason(), "unable to determine common point");
ASSERT_EQUALS(1,
countLogLinesContaining(
"Missing index name in createIndexes operation on rollback, document: "));
@@ -864,7 +864,7 @@ TEST_F(RSRollbackTest, RollbackUnknownCommand) {
_coordinator,
_replicationProcess.get());
ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, status.code());
- ASSERT_EQUALS(18752, status.location());
+ ASSERT_STRING_CONTAINS(status.reason(), "unable to determine common point");
}
TEST_F(RSRollbackTest, RollbackDropCollectionCommand) {
@@ -1820,7 +1820,7 @@ TEST_F(RSRollbackTest, RollbackCollectionModificationCommandInvalidCollectionOpt
_coordinator,
_replicationProcess.get());
ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, status.code());
- ASSERT_EQUALS(18753, status.location());
+ ASSERT_STRING_CONTAINS(status.reason(), "Failed to parse options");
}
TEST(RSRollbackTest, LocalEntryWithoutNsIsFatal) {
@@ -2048,12 +2048,12 @@ TEST_F(RSRollbackTest, RollbackReturnsImmediatelyOnFailureToTransitionToRollback
ASSERT_EQUALS(MemberState(MemberState::RS_SECONDARY), _coordinator->getMemberState());
}
-DEATH_TEST_F(RSRollbackTest,
- RollbackUnrecoverableRollbackErrorTriggersFatalAssertion,
- "Unable to complete rollback. A full resync may be needed: "
- "UnrecoverableRollbackError: need to rollback, but unable to determine common point "
- "between local and remote oplog: InvalidSyncSource: remote oplog empty or unreadable "
- "@ 18752") {
+DEATH_TEST_F(
+ RSRollbackTest,
+ RollbackUnrecoverableRollbackErrorTriggersFatalAssertion,
+ "Unable to complete rollback. A full resync may be needed: "
+ "UnrecoverableRollbackError: need to rollback, but unable to determine common point "
+ "between local and remote oplog: InvalidSyncSource: remote oplog empty or unreadable") {
// rollback() should abort on getting UnrecoverableRollbackError from syncRollback(). An empty
// local oplog will make syncRollback() return the intended error.
OplogInterfaceMock localOplogWithSingleOplogEntry({makeNoopOplogEntryAndRecordId(Seconds(1))});
diff --git a/src/mongo/db/storage/mmap_v1/btree/btree_logic.cpp b/src/mongo/db/storage/mmap_v1/btree/btree_logic.cpp
index cb35765e131..c50a8c15162 100644
--- a/src/mongo/db/storage/mmap_v1/btree/btree_logic.cpp
+++ b/src/mongo/db/storage/mmap_v1/btree/btree_logic.cpp
@@ -1058,7 +1058,7 @@ Status BtreeLogic<BtreeLayout>::_find(OperationContext* opCtx,
dupsCheckedYet = true;
if (exists(opCtx, key)) {
if (wouldCreateDup(opCtx, key, genericRecordLoc)) {
- return Status(ErrorCodes::DuplicateKey, dupKeyError(key), 11000);
+ return Status(ErrorCodes::DuplicateKey, dupKeyError(key));
} else {
return Status(ErrorCodes::DuplicateKeyValue,
"key/value already in index");
@@ -1069,7 +1069,7 @@ Status BtreeLogic<BtreeLayout>::_find(OperationContext* opCtx,
if (fullKey.recordLoc == recordLoc) {
return Status(ErrorCodes::DuplicateKeyValue, "key/value already in index");
} else {
- return Status(ErrorCodes::DuplicateKey, dupKeyError(key), 11000);
+ return Status(ErrorCodes::DuplicateKey, dupKeyError(key));
}
}
}
diff --git a/src/mongo/db/storage/mmap_v1/record_store_v1_capped.cpp b/src/mongo/db/storage/mmap_v1/record_store_v1_capped.cpp
index 47b65e7dd16..6a3c02b562f 100644
--- a/src/mongo/db/storage/mmap_v1/record_store_v1_capped.cpp
+++ b/src/mongo/db/storage/mmap_v1/record_store_v1_capped.cpp
@@ -105,8 +105,7 @@ StatusWith<DiskLoc> CappedRecordStoreV1::allocRecord(OperationContext* opCtx,
ErrorCodes::DocTooLargeForCapped,
mongoutils::str::stream() << "document is larger than capped size " << lenToAlloc
<< " > "
- << storageSize(opCtx),
- 16328);
+ << storageSize(opCtx));
}
}
DiskLoc loc;
@@ -165,8 +164,7 @@ StatusWith<DiskLoc> CappedRecordStoreV1::allocRecord(OperationContext* opCtx,
<< " size: "
<< lenToAlloc
<< " storageSize:"
- << storageSize(opCtx),
- 28575);
+ << storageSize(opCtx));
}
continue;
}
diff --git a/src/mongo/db/storage/mmap_v1/record_store_v1_capped_test.cpp b/src/mongo/db/storage/mmap_v1/record_store_v1_capped_test.cpp
index f12f3328e72..2d95e1dad13 100644
--- a/src/mongo/db/storage/mmap_v1/record_store_v1_capped_test.cpp
+++ b/src/mongo/db/storage/mmap_v1/record_store_v1_capped_test.cpp
@@ -381,7 +381,7 @@ TEST(CappedRecordStoreV1, OversizedRecordHuge) {
StatusWith<RecordId> status = rs.insertRecord(&opCtx, zeros, 16000, false);
ASSERT_EQUALS(status.getStatus(), ErrorCodes::DocTooLargeForCapped);
- ASSERT_EQUALS(status.getStatus().location(), 16328);
+ ASSERT_STRING_CONTAINS(status.getStatus().reason(), "larger than capped size");
}
// Smaller than storageSize, but larger than usable space (fails late)
@@ -403,7 +403,7 @@ TEST(CappedRecordStoreV1, OversizedRecordMedium) {
StatusWith<RecordId> status =
rs.insertRecord(&opCtx, zeros, 1004 - MmapV1RecordHeader::HeaderSize, false);
ASSERT_EQUALS(status.getStatus(), ErrorCodes::DocTooLargeForCapped);
- ASSERT_EQUALS(status.getStatus().location(), 28575);
+ ASSERT_STRING_CONTAINS(status.getStatus().reason(), "doesn't fit");
}
//
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp
index db1d8c048f4..dcfc241e9a4 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp
@@ -256,14 +256,15 @@ WiredTigerIndex::WiredTigerIndex(OperationContext* ctx,
auto version = WiredTigerUtil::checkApplicationMetadataFormatVersion(
ctx, uri, kMinimumIndexVersion, kMaximumIndexVersion);
if (!version.isOK()) {
- str::stream ss;
Status versionStatus = version.getStatus();
- ss << versionStatus.reason() << " Index: {name: " << desc->indexName()
- << ", ns: " << desc->parentNS() << "} - version too new for this mongod."
- << " See http://dochub.mongodb.org/core/3.4-index-downgrade for detailed"
- << " instructions on how to handle this error.";
Status indexVersionStatus(
- ErrorCodes::UnsupportedFormat, ss.ss.str(), versionStatus.location());
+ ErrorCodes::UnsupportedFormat,
+ str::stream() << versionStatus.reason() << " Index: {name: " << desc->indexName()
+ << ", ns: "
+ << desc->parentNS()
+ << "} - version too new for this mongod."
+ << " See http://dochub.mongodb.org/core/3.4-index-downgrade for detailed"
+ << " instructions on how to handle this error.");
fassertFailedWithStatusNoTrace(28579, indexVersionStatus);
}
_keyStringVersion =
diff --git a/src/mongo/db/views/durable_view_catalog.cpp b/src/mongo/db/views/durable_view_catalog.cpp
index 9426e941cf7..bfec32e9409 100644
--- a/src/mongo/db/views/durable_view_catalog.cpp
+++ b/src/mongo/db/views/durable_view_catalog.cpp
@@ -154,15 +154,14 @@ void DurableViewCatalogImpl::upsert(OperationContext* opCtx,
args.fromMigrate = false;
const bool assumeIndexesAreAffected = true;
- auto res = systemViews->updateDocument(opCtx,
- id,
- oldView,
- view,
- enforceQuota,
- assumeIndexesAreAffected,
- &CurOp::get(opCtx)->debug(),
- &args);
- uassertStatusOK(res);
+ systemViews->updateDocument(opCtx,
+ id,
+ oldView,
+ view,
+ enforceQuota,
+ assumeIndexesAreAffected,
+ &CurOp::get(opCtx)->debug(),
+ &args);
}
}
diff --git a/src/mongo/dbtests/multikey_paths_test.cpp b/src/mongo/dbtests/multikey_paths_test.cpp
index 6caa614c495..ed64a4c3045 100644
--- a/src/mongo/dbtests/multikey_paths_test.cpp
+++ b/src/mongo/dbtests/multikey_paths_test.cpp
@@ -293,16 +293,15 @@ TEST_F(MultikeyPathsTest, PathsUpdatedOnDocumentUpdate) {
const bool indexesAffected = true;
OpDebug* opDebug = nullptr;
OplogUpdateEntryArgs args;
- collection
- ->updateDocument(_opCtx.get(),
- record->id,
- oldDoc,
- BSON("_id" << 0 << "a" << 5 << "b" << BSON_ARRAY(1 << 2 << 3)),
- enforceQuota,
- indexesAffected,
- opDebug,
- &args)
- .status_with_transitional_ignore();
+ collection->updateDocument(
+ _opCtx.get(),
+ record->id,
+ oldDoc,
+ BSON("_id" << 0 << "a" << 5 << "b" << BSON_ARRAY(1 << 2 << 3)),
+ enforceQuota,
+ indexesAffected,
+ opDebug,
+ &args);
wuow.commit();
}
}
diff --git a/src/mongo/dbtests/query_stage_count.cpp b/src/mongo/dbtests/query_stage_count.cpp
index 0663a1ce626..a66c4d5ab38 100644
--- a/src/mongo/dbtests/query_stage_count.cpp
+++ b/src/mongo/dbtests/query_stage_count.cpp
@@ -126,16 +126,14 @@ public:
BSONObj oldDoc = _coll->getRecordStore()->dataFor(&_opCtx, oldrecordId).releaseToBson();
OplogUpdateEntryArgs args;
args.nss = _coll->ns();
- _coll
- ->updateDocument(&_opCtx,
- oldrecordId,
- Snapshotted<BSONObj>(_opCtx.recoveryUnit()->getSnapshotId(), oldDoc),
- newDoc,
- false,
- true,
- NULL,
- &args)
- .status_with_transitional_ignore();
+ _coll->updateDocument(&_opCtx,
+ oldrecordId,
+ Snapshotted<BSONObj>(_opCtx.recoveryUnit()->getSnapshotId(), oldDoc),
+ newDoc,
+ false,
+ true,
+ NULL,
+ &args);
wunit.commit();
}
diff --git a/src/mongo/dbtests/query_stage_sort.cpp b/src/mongo/dbtests/query_stage_sort.cpp
index bb9082c81fb..2c698748b6c 100644
--- a/src/mongo/dbtests/query_stage_sort.cpp
+++ b/src/mongo/dbtests/query_stage_sort.cpp
@@ -350,18 +350,19 @@ public:
set<RecordId>::iterator it = recordIds.begin();
Snapshotted<BSONObj> oldDoc = coll->docFor(&_opCtx, *it);
- OID updatedId = oldDoc.value().getField("_id").OID();
- SnapshotId idBeforeUpdate = oldDoc.snapshotId();
+ const OID updatedId = oldDoc.value().getField("_id").OID();
+ const SnapshotId idBeforeUpdate = oldDoc.snapshotId();
// We purposefully update the document to have a 'foo' value greater than limit().
// This allows us to check that we don't return the new copy of a doc by asserting
// foo < limit().
- BSONObj newDoc = BSON("_id" << updatedId << "foo" << limit() + 10);
+ auto newDoc = [&](const Snapshotted<BSONObj>& oldDoc) {
+ return BSON("_id" << oldDoc.value()["_id"] << "foo" << limit() + 10);
+ };
OplogUpdateEntryArgs args;
args.nss = coll->ns();
{
WriteUnitOfWork wuow(&_opCtx);
- coll->updateDocument(&_opCtx, *it, oldDoc, newDoc, false, false, NULL, &args)
- .status_with_transitional_ignore();
+ coll->updateDocument(&_opCtx, *it, oldDoc, newDoc(oldDoc), false, false, NULL, &args);
wuow.commit();
}
exec->restoreState();
@@ -379,8 +380,8 @@ public:
oldDoc = coll->docFor(&_opCtx, *it);
{
WriteUnitOfWork wuow(&_opCtx);
- coll->updateDocument(&_opCtx, *it++, oldDoc, newDoc, false, false, NULL, &args)
- .status_with_transitional_ignore();
+ coll->updateDocument(
+ &_opCtx, *it++, oldDoc, newDoc(oldDoc), false, false, NULL, &args);
wuow.commit();
}
}
diff --git a/src/mongo/logger/redaction.cpp b/src/mongo/logger/redaction.cpp
index 1ec2d1e7cf9..3fff4974f35 100644
--- a/src/mongo/logger/redaction.cpp
+++ b/src/mongo/logger/redaction.cpp
@@ -65,8 +65,6 @@ std::string redact(const Status& statusToRedact) {
sb << statusToRedact.codeString();
if (!statusToRedact.isOK())
sb << ": " << kRedactionDefaultMask;
- if (statusToRedact.location() != 0)
- sb << " @ " << statusToRedact.location();
return sb.str();
}
diff --git a/src/mongo/logger/redaction_test.cpp b/src/mongo/logger/redaction_test.cpp
index 46c140eefb8..da8abc4ee96 100644
--- a/src/mongo/logger/redaction_test.cpp
+++ b/src/mongo/logger/redaction_test.cpp
@@ -46,12 +46,6 @@ TEST(RedactStatusTest, BasicStatus) {
ASSERT_EQ(redact(status), "InternalError: " + kRedactionDefaultMask);
}
-TEST(RedactStatusTest, StatusWithLocation) {
- logger::globalLogDomain()->setShouldRedactLogs(true);
- Status status(ErrorCodes::InternalError, kMsg, 777);
- ASSERT_EQ(redact(status), "InternalError: " + kRedactionDefaultMask + " @ 777");
-}
-
TEST(RedactStatusTest, StatusOK) {
logger::globalLogDomain()->setShouldRedactLogs(true);
ASSERT_EQ(redact(Status::OK()), "OK");
diff --git a/src/mongo/s/client/shard_remote.cpp b/src/mongo/s/client/shard_remote.cpp
index e75af4c8554..4617ef23f50 100644
--- a/src/mongo/s/client/shard_remote.cpp
+++ b/src/mongo/s/client/shard_remote.cpp
@@ -336,7 +336,7 @@ StatusWith<Shard::QueryResponse> ShardRemote::_exhaustiveFindOnConfig(
updateReplSetMonitor(host.getValue(), status);
if (!status.isOK()) {
- if (status.compareCode(ErrorCodes::ExceededTimeLimit)) {
+ if (status == ErrorCodes::ExceededTimeLimit) {
LOG(0) << "Operation timed out " << causedBy(status);
}
return status;
diff --git a/src/mongo/util/assert_util.h b/src/mongo/util/assert_util.h
index 99440a57503..f0f9e42424d 100644
--- a/src/mongo/util/assert_util.h
+++ b/src/mongo/util/assert_util.h
@@ -322,10 +322,7 @@ inline void fassertNoTraceWithLocation(int msgid,
::mongo::uassertStatusOKWithLocation(__VA_ARGS__, __FILE__, __LINE__)
inline void uassertStatusOKWithLocation(const Status& status, const char* file, unsigned line) {
if (MONGO_unlikely(!status.isOK())) {
- uassertedWithLocation((status.location() != 0 ? status.location() : status.code()),
- status.reason(),
- file,
- line);
+ uassertedWithLocation(status.code(), status.reason(), file, line);
}
}
@@ -386,10 +383,7 @@ inline void fassertStatusOKWithLocation(int msgid,
::mongo::massertStatusOKWithLocation(__VA_ARGS__, __FILE__, __LINE__)
inline void massertStatusOKWithLocation(const Status& status, const char* file, unsigned line) {
if (MONGO_unlikely(!status.isOK())) {
- msgassertedWithLocation((status.location() != 0 ? status.location() : status.code()),
- status.reason(),
- file,
- line);
+ msgassertedWithLocation(status.code(), status.reason(), file, line);
}
}
@@ -401,11 +395,7 @@ inline void massertNoTraceStatusOKWithLocation(const Status& status,
unsigned line) {
if (MONGO_unlikely(!status.isOK())) {
[&]() MONGO_COMPILER_COLD_FUNCTION {
- msgassertedNoTraceWithLocation(
- (status.location() != 0 ? status.location() : status.code()),
- status.reason(),
- file,
- line);
+ msgassertedNoTraceWithLocation(status.code(), status.reason(), file, line);
}();
MONGO_COMPILER_UNREACHABLE;
}