sql >> Database teknologi >  >> NoSQL >> MongoDB

MongoDB Node.js native driver sluger lydløst `bulkWrite` undtagelse

Så som kommenteret, "Det er en fejl". Specifikt er fejlen lige her :

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

Problemet er, at "svaret" ( eller r ) i tilbagekaldet, som bliver pakket ind i et Promise er faktisk ikke null , og på trods af fejlen er betingelsen derfor ikke true og reject(err) kaldes ikke, men snarere resolve(r) bliver sendt, og derfor betragtes dette ikke som en undtagelse.

Korrigering ville kræve noget triage, men du kan enten 'omgå' som nævnt ved at inspicere writeErrors egenskab i svaret fra den aktuelle bulkWrite() implementering eller overvej et af de andre alternativer som:

Brug af Bulk API-metoderne direkte:

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

})();

Helt i orden, men har selvfølgelig problemet med ikke at gå naturligt tilbage på serverimplementeringer uden Bulk API-understøttelse til at bruge de ældre API-metoder i stedet for.

Manuel indpakning af løftet

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

})();

Som nævnt ligger problemet i implementeringen af ​​hvordan bulkWrite() vender tilbage som et Promise . Så i stedet kan du kode med callback() formular og lav dit eget Promise indpakning for at handle, som du forventer.

Igen som nævnt, har brug for et JIRA-problem og Triage, som er den korrekte måde at håndtere undtagelserne på. Men det bliver forhåbentlig snart løst. I mellemtiden skal du vælge en tilgang fra oven.




  1. Automatisering og administration af MongoDB i skyen

  2. Express.js/Mongoose brugerroller og tilladelser

  3. En introduktion til Percona Server til MongoDB 4.2

  4. Ignorer specialtegn før matchbetingelser