Skip to content

Commit edcbe96

Browse files
dongxinEricapkar
authored andcommitted
The errors returned by the server must always contain the $err key (#169)
* The errors returned by the server must always contain the $err key * Audit all places the server sends back 'errmsg' and added '$err' along with it
1 parent 3d02533 commit edcbe96

File tree

4 files changed

+68
-7
lines changed

4 files changed

+68
-7
lines changed

src/ExtCmd.actor.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,8 @@ struct GetLogCmd {
230230
if (query->ns.first != "admin") {
231231
// clang-format off
232232
reply->addDocument((bob << "ok" << 0.0 <<
233-
"errmsg" << "access denied; use admin db").obj());
233+
"errmsg" << "access denied; use admin db" <<
234+
"$err" << "access denied; use admin db").obj());
234235
// clang-format on
235236
return reply;
236237
}
@@ -286,6 +287,7 @@ struct ReplSetGetStatusCmd {
286287
// FIXME: what do we really want to report here?
287288
bob.append("ok", 0.0);
288289
bob.append("errmsg", "not really talking to mongodb");
290+
bob.append("$err", "not really talking to mongodb");
289291

290292
reply->addDocument(bob.obj());
291293

@@ -536,7 +538,12 @@ ACTOR static Future<Reference<ExtMsgReply>> doFindAndModify(Reference<ExtConnect
536538
bson::BSONObj replyObj = bob.obj().getOwned();
537539
reply->addDocument(replyObj);
538540
} catch (Error& e) {
539-
reply->addDocument(BSON("errmsg" << e.what() << "code" << e.code() << "ok" << 1.0));
541+
// clang-format off
542+
reply->addDocument(BSON("errmsg" << e.what() <<
543+
"$err" << e.what() <<
544+
"code" << e.code() <<
545+
"ok" << 1.0));
546+
// clang-format on
540547
}
541548

542549
return reply;
@@ -662,7 +669,12 @@ ACTOR static Future<Reference<ExtMsgReply>> doCreateIndexes(Reference<ExtConnect
662669
Void _ = wait(waitForAll(f));
663670
reply->addDocument(BSON("ok" << 1.0));
664671
} catch (Error& e) {
665-
reply->addDocument(BSON("ok" << 0.0 << "errmsg" << e.what() << "code" << e.code()));
672+
// clang-format off
673+
reply->addDocument(BSON("ok" << 0.0 <<
674+
"$err" << e.what() <<
675+
"errmsg" << e.what() <<
676+
"code" << e.code()));
677+
// clang-format on
666678
}
667679
return reply;
668680
}
@@ -954,7 +966,12 @@ ACTOR static Future<Reference<ExtMsgReply>> insertAndReply(Reference<ExtConnecti
954966
// one FDB transaction.
955967
bson::BSONArrayBuilder arrayBuilder;
956968
for (int i = 0; i < docs.size(); i++) {
957-
arrayBuilder << BSON("index" << i << "code" << e.code() << "errmsg" << e.what());
969+
// clang-format off
970+
arrayBuilder << BSON("index" << i <<
971+
"code" << e.code() <<
972+
"$err" << e.what() <<
973+
"errmsg" << e.what());
974+
// clang-format on
958975
}
959976
reply->addDocument(BSON("ok" << 1 << "n" << 0 << "writeErrors" << arrayBuilder.arr()));
960977
}

src/ExtMsg.actor.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,10 @@ ACTOR Future<Void> runCommand(Reference<ExtConnection> nmc,
249249

250250
if (e.code() == error_code_bad_dispatch) {
251251
bob.append("errmsg", format("no such cmd: %s", cmd.c_str()));
252+
bob.append("$err", format("no such cmd: %s", cmd.c_str()));
252253
} else {
253254
bob.append("errmsg", format("command [%s] failed with err: %s", cmd.c_str(), e.what()));
255+
bob.append("$err", format("command [%s] failed with err: %s", cmd.c_str(), e.what()));
254256
}
255257
bob.append("bad cmd", query->query.toString());
256258
bob.append("ok", 0);
@@ -1094,7 +1096,12 @@ ACTOR Future<WriteCmdResult> doUpdateCmd(Namespace ns,
10941096
}
10951097
} catch (Error& e) {
10961098
TraceEvent(SevError, "ExtMsgUpdateFailure").error(e);
1097-
cmdResult.writeErrors.push_back(BSON("index" << idx << "code" << e.code() << "errmsg" << e.what()));
1099+
// clang-format off
1100+
cmdResult.writeErrors.push_back(BSON("index" << idx <<
1101+
"code" << e.code() <<
1102+
"$err" << e.what() <<
1103+
"errmsg" << e.what()));
1104+
// clang-format on
10981105
if (ordered)
10991106
break;
11001107
}
@@ -1238,7 +1245,12 @@ ACTOR Future<WriteCmdResult> doDeleteCmd(Namespace ns,
12381245
nrDeletedRecords += deletedRecords;
12391246
} catch (Error& e) {
12401247
TraceEvent(SevError, "ExtMsgDeleteFailure").error(e);
1241-
writeErrors.push_back(BSON("index" << idx << "code" << e.code() << "errmsg" << e.what()));
1248+
// clang-format off
1249+
writeErrors.push_back(BSON("index" << idx <<
1250+
"code" << e.code() <<
1251+
"$err" << e.what() <<
1252+
"errmsg" << e.what()));
1253+
// clang-format on
12421254
if (ordered)
12431255
break;
12441256
}

src/ExtStructs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ struct WriteCmdResult {
6161
std::vector<Standalone<StringRef>> upsertedOIDList;
6262

6363
/**
64-
* Array of write errors. Each entry has fields - 'index', 'code' and 'errmsg'. 'index'
64+
* Array of write errors. Each entry has fields - 'index', 'code' '$err' and 'errmsg'. 'index'
6565
* points to write command in the request. So, separate write error for each write failed.
6666
*/
6767
std::vector<bson::BSONObj> writeErrors;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/python
2+
#
3+
# test_errors.py
4+
#
5+
# This source file is part of the FoundationDB open source project
6+
#
7+
# Copyright 2013-2019 Apple Inc. and the FoundationDB project authors
8+
#
9+
# Licensed under the Apache License, Version 2.0 (the "License");
10+
# you may not use this file except in compliance with the License.
11+
# You may obtain a copy of the License at
12+
#
13+
# http://www.apache.org/licenses/LICENSE-2.0
14+
#
15+
# Unless required by applicable law or agreed to in writing, software
16+
# distributed under the License is distributed on an "AS IS" BASIS,
17+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
# See the License for the specific language governing permissions and
19+
# limitations under the License.
20+
#
21+
# MongoDB is a registered trademark of MongoDB, Inc.
22+
#
23+
24+
from pymongo.errors import OperationFailure
25+
26+
def test_error_reply(fixture_db):
27+
try:
28+
fixture_db.command("someTotallyRandomCmd")
29+
except OperationFailure as e:
30+
serverErrObj = e.details
31+
assert serverErrObj['$err'] != None
32+
assert "no such cmd: sometotallyrandomcmd" in serverErrObj['$err']

0 commit comments

Comments
 (0)