Quindi, come commentato, "È un bug". In particolare il bug è proprio qui :
// 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);
});
});
Il problema è che la "risposta" ( o r
) nella callback che viene racchiusa in una Promise
in realtà non è null
, e quindi nonostante l'errore sia presente la condizione non è quindi true
e reject(err)
non viene chiamato, ma piuttosto il resolve(r)
viene inviato e quindi questa non è considerata un'eccezione.
La correzione richiederebbe un po' di valutazione, ma puoi 'ovviare' come menzionato ispezionando writeErrors
proprietà nella risposta dall'attuale bulkWrite()
implementazione o considerare una delle altre alternative come:
Utilizzando direttamente i metodi dell'API Bulk:
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();
}
})();
Perfettamente a posto, ma ovviamente ha il problema di non regredire naturalmente sulle implementazioni del server senza il supporto dell'API in blocco per utilizzare invece i metodi dell'API legacy.
Confezione manuale della promessa
(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);
}
})();
Come notato, il problema risiede nell'implementazione di come bulkWrite()
sta tornando come una Promise
. Quindi puoi invece programmare con il callback()
forma e fai la tua Promise
avvolgere per agire come ti aspetti.
Anche in questo caso, come notato, è necessario un problema JIRA e un Triage in cui è il modo corretto di gestire le eccezioni. Ma speriamo si risolva presto. Nel frattempo, scegli un approccio dall'alto.