MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Родният драйвер на MongoDB Node.js тихо поглъща изключение `bulkWrite`

Така че, както беше коментирано, „Това е грешка“. По-конкретно грешката е точно тук :

 // 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);
    });
  });

Проблемът е, че „отговорът“ ( или r ) в обратното извикване, което е обвито в Promise всъщност не е null и следователно въпреки наличието на грешката, условието следователно не е true и reject(err) не се извиква, а по-скоро resolve(r) се изпраща и следователно това не се счита за изключение.

Коригирането ще изисква известно сортиране, но можете или да „заобиколите“, както беше споменато, като проверите writeErrors свойство в отговора от текущия bulkWrite() реализация или разгледайте една от другите алтернативи като:

Използване на груповите 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();
  }

})();

Напълно добре, но, разбира се, има проблем, че няма естествено регресиране на сървърните имплементации без групова поддръжка на API за използване на наследените API методи вместо това.

Ръчно опаковане на обещанието

(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);
  }

})();

Както беше отбелязано, проблемът се крие в изпълнението на това как bulkWrite() се връща като Promise . Така че вместо това можете да кодирате с callback() формуляр и направете свое собствено Promise обвиване, за да действа както очаквате.

Отново, както беше отбелязано, има нужда от проблем с JIRA и Triage, който е правилният начин за справяне с изключенията. Но се надяваме скоро да се разреши. Междувременно изберете подход отгоре.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Часовникът Grunt Serve хвърля предупреждение EBUSY върху mongod.lock

  2. Проверка на здравето на Mongodb стъпка по стъпка

  3. Node.js – Създаване на връзки с Mongoose

  4. Къде MongoDB съхранява своите документи?

  5. Връща само стойност на масив в проекция на mongo