The script below has a bug in the mongo bulkWrite op syntax: $setOnInsert: { count:0 },
is unnecessary and thus mongo throws an exception: \"Cannot update \'cou
So as commented, "It's a bug". Specifically the bug is right here:
// Return a Promise
return new this.s.promiseLibrary(function(resolve, reject) {
bulkWrite(self, operations, options, function(err, r) {
if(err && r == null) return reject(err);
resolve(r);
});
});
The problem is that the "response" ( or r
) in the callback which is being wrapped in a Promise
is not actually null
, and therefore despite the error being present the condition is therefore not true
and reject(err)
is not being called, but rather the resolve(r)
is being sent and hence this is not considered an exception.
Correcting would need some triage, but you can either 'work around' as mentioned by inspecting the writeErrors
property in the response from the current bulkWrite()
implementation or consider one of the other alternatives as:
const MongoClient = require('mongodb').MongoClient,
uri = 'mongodb://localhost:27017/myNewDb';
(async () => {
let db;
try {
db = await MongoClient.connect(uri);
let bulk = db.collection('myNewCollection').initializeOrderedBulkOp();
bulk.find({ foo: 'bar' }).upsert().updateOne({
$setOnInsert: { count: 0 },
$inc: { count: 0 }
});
let result = await bulk.execute();
console.log(JSON.stringify(result,undefined,2));
} catch(e) {
console.error(e);
} finally {
db.close();
}
})();
Perfectly fine but of course has the issue of not naturally regressing on server implementations without Bulk API support to using the legacy API methods instead.
(async () => {
let db = await require('mongodb').MongoClient.connect('mongodb://localhost:27017/myNewDb');
let mongoOps = [{
updateOne: {
filter: { foo: "bar" },
update: {
$setOnInsert: { count:0 },
$inc: { count:1 },
},
upsert: true,
}
}];
try {
let result = await new Promise((resolve,reject) => {
db.collection("myNewCollection").bulkWrite(mongoOps, (err,r) => {
if (err) reject(err);
resolve(r);
});
});
console.log(JSON.stringify(result,undefined,2));
console.log("Success!");
} catch(e) {
console.log("Failed:");
console.log(e);
}
})();
As noted the problem lies within the implementation of how bulkWrite()
is returning as a Promise
. So instead you can code with the callback()
form and do your own Promise
wrapping in order to act how you expect it to.
Again as noted, needs a JIRA issue and Triage to which is the correct way to handle the exceptions. But hopefully gets resolved soon. In the meantime, pick an approach from above.