summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Midvidy <amidvidy@gmail.com>2016-02-24 15:43:27 -0500
committerRamon Fernandez <ramon@mongodb.com>2016-02-25 07:39:22 -0500
commit6ccebf255b6a3a278780203f29d2be43d10830cc (patch)
tree7084e18184b9eeeeda3aebf6f28e624a4458810b
parent8a133eea3bdae3386c48091e8931e39d8a6bbf27 (diff)
downloadmongo-6ccebf255b6a3a278780203f29d2be43d10830cc.tar.gz
SERVER-22184 check for the new error format in peekError
(cherry picked from commit 3a5c0f9bcb46f083863622e0d734cf29023e7275)
-rw-r--r--jstests/sharding/error_propagation.js23
-rw-r--r--src/mongo/client/dbclientcursor.cpp5
2 files changed, 27 insertions, 1 deletions
diff --git a/jstests/sharding/error_propagation.js b/jstests/sharding/error_propagation.js
new file mode 100644
index 00000000000..9948da66190
--- /dev/null
+++ b/jstests/sharding/error_propagation.js
@@ -0,0 +1,23 @@
+(function() {
+ // Tests that errors encountered on shards are correctly returned to the client when mongos uses
+ // the legacy DBClientCursor method of executing commands on shards. We use aggregation here
+ // specifically because it is one of the few query paths that still uses the legacy DBClient
+ // classes in mongos.
+ "use strict";
+
+ var st = new ShardingTest({mongos: 1, shards: 1, rs: {nodes: 3}});
+
+ var db = st.getDB('test');
+ db.setSlaveOk(true);
+
+ assert.writeOK(db.foo.insert({a:1}, {writeConcern: {w:3}}));
+ assert.commandWorked(db.runCommand({aggregate: 'foo',
+ pipeline: [{$project: {total: {'$add': ['$a', 1]}}}]}));
+
+ assert.writeOK(db.foo.insert({a: [1, 2]}, {writeConcern: {w:3}}));
+
+ var res = db.runCommand({aggregate: 'foo',
+ pipeline: [{$project: {total: {'$add': ['$a', 1]}}}]});
+ assert.commandFailed(res);
+ assert.eq("$add only supports numeric or date types, not Array", res.errmsg, printjson(res));
+}());
diff --git a/src/mongo/client/dbclientcursor.cpp b/src/mongo/client/dbclientcursor.cpp
index 861aa905547..2e0a5bdade3 100644
--- a/src/mongo/client/dbclientcursor.cpp
+++ b/src/mongo/client/dbclientcursor.cpp
@@ -417,7 +417,10 @@ bool DBClientCursor::peekError(BSONObj* error) {
peek(v, 1);
verify(v.size() == 1);
- verify(hasErrField(v[0]));
+ // We check both the legacy error format, and the new error format. hasErrField checks for
+ // $err, and getStatusFromCommandResult checks for modern errors of the form '{ok: 0.0, code:
+ // <...>, errmsg: ...}'.
+ verify(hasErrField(v[0]) || !getStatusFromCommandResult(v[0]).isOK());
if (error)
*error = v[0].getOwned();