Takže jak bylo komentováno:"Je to chyba". Chyba je konkrétně přímo zde :
// 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);
});
});
Problém je v tom, že "odpověď" (nebo r
) ve zpětném volání, které je zabaleno do Promise
ve skutečnosti není null
, a proto i přes přítomnost chyby není podmínka true
a reject(err)
není voláno, ale spíše resolve(r)
se odesílá, a proto to není považováno za výjimku.
Oprava by vyžadovala určité třídění, ale můžete to buď „obejít“, jak bylo zmíněno, prozkoumáním writeErrors
vlastnost v odpovědi z aktuálního bulkWrite()
implementaci nebo zvažte jednu z dalších alternativ jako:
Přímé použití metod Bulk API:
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();
}
})();
Naprosto v pořádku, ale má samozřejmě problém s tím, že se na serverových implementacích bez podpory Bulk API přirozeně nevrací k použití starších metod API.
Ruční zabalení slibu
(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);
}
})();
Jak bylo uvedeno, problém spočívá v implementaci způsobu bulkWrite()
se vrací jako Promise
. Místo toho můžete kódovat pomocí callback()
formulář a udělejte svůj vlastní Promise
balení, aby se chovalo tak, jak očekáváte.
Opět, jak bylo uvedeno, potřebuje problém JIRA a Triage, což je správný způsob, jak zpracovat výjimky. Ale snad se to brzy vyřeší. Mezitím si vyberte přístup shora.