Tak jak skomentował:„To błąd”. W szczególności błąd jest tutaj :
// 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);
});
});
Problem polega na tym, że "odpowiedź" ( lub r
) w wywołaniu zwrotnym, które jest opakowane w Promise
w rzeczywistości nie jest null
, a zatem pomimo obecności błędu warunek nie jest true
i reject(err)
nie jest wywoływana, ale raczej resolve(r)
jest wysyłany i dlatego nie jest to uważane za wyjątek.
Poprawianie wymagałoby trochę triage, ale możesz albo "obejść", jak wspomniano, sprawdzając writeErrors
właściwość w odpowiedzi z bieżącego bulkWrite()
wdrożenie lub rozważ jedną z innych alternatyw jako:
Bezpośrednie użycie 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();
}
})();
Idealnie w porządku, ale oczywiście ma problem z naturalnym cofaniem się implementacji serwera bez obsługi Bulk API do korzystania ze starszych metod API.
Ręczne zawijanie obietnicy
(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 zauważono, problem leży w implementacji sposobu, w jaki bulkWrite()
powraca jako Promise
. Zamiast tego możesz kodować za pomocą callback()
formularz i zrób własną Promise
zawijanie, aby zachowywać się tak, jak tego oczekujesz.
Ponownie, jak wspomniano, potrzebuje problemu JIRA i Triage, do którego jest właściwy sposób obsługi wyjątków. Ale miejmy nadzieję, że wkrótce zostanie rozwiązany. W międzyczasie wybierz podejście od góry.