sql >> Databáze >  >> NoSQL >> MongoDB

Nativní ovladač MongoDB Node.js tiše spolkne výjimku `bulkWrite`

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.




  1. docker-compose:spojení redis mezi kontejnery bylo odmítnuto

  2. MongoError:Topologie je uzavřena, připojení se zdá být spojeno s MongoClient.close() a klient při jejím používání nebude fungovat

  3. 3 způsoby, jak skrýt index z plánu dotazů v MongoDB

  4. Jak otestovat celer s django na počítači se systémem Windows