当前位置: 首页 > 面试题库 >

MongoDB Node.js本机驱动程序无声地吞没了“ bulkWrite”异常

淳于凯
2023-03-14
问题内容

下面的脚本在mongo bulkWrite op语法中存在一个错误:$setOnInsert: { count:0 },不必要,因此mongo引发异常:“无法同时更新’count’和’count’”。

问题是,node.js驱动程序似乎无法捕获它。此脚本记录“成功!” 到控制台。

(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 {
    await db.collection("myNewCollection").bulkWrite(mongoOps);
    console.log("Success!");
  } catch(e) {
    console.log("Failed:");
    console.log(e);
  }

})();

检查db.system.profile.find({})db.setProfileLevel(2)我们可以看到异常:

{
    "op" : "update",
    "ns" : "myNewDb.myNewCollection",
    "query" : {
        "foo" : "bar"
    },
    "updateobj" : {
        "$setOnInsert" : {
            "count" : 0
        },
        "$inc" : {
            "count" : 1
        }
    },
    "keyUpdates" : 0,
    "writeConflicts" : 0,
    "numYield" : 0,
    "locks" : {
        "Global" : {
            "acquireCount" : {
                "r" : NumberLong(1),
                "w" : NumberLong(1)
            }
        },
        "Database" : {
            "acquireCount" : {
                "w" : NumberLong(1)
            }
        },
        "Collection" : {
            "acquireCount" : {
                "w" : NumberLong(1)
            }
        }
    },
    "exception" : "Cannot update 'count' and 'count' at the same time",
    "exceptionCode" : 16836,
    "millis" : 0,
    "execStats" : {},
    "ts" : ISODate("2017-10-12T01:57:03.008Z"),
    "client" : "127.0.0.1",
    "allUsers" : [],
    "user" : ""
}

为什么驾驶员会吞下这样的错误?我绝对看起来像是个错误,但我想我想先确定一下。


问题答案:

因此评论说,“这是一个错误”。具体来说,错误就在这里:

 // 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包装在a中的回调中的“响应”(或)Promise实际上不是null,因此尽管存在错误,也不会truereject(err)不会调用该条件,而是resolve(r)正在发送并因此这不视为例外。

更正需要一些分类,但是您可以通过检查writeErrors当前bulkWrite()实现的响应中的属性来“解决”,也可以考虑以下其他替代方法之一:

直接使用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();
  }

})();

完全没问题,但是当然存在这样的问题:在没有Bulk 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()以a形式返回Promise。因此,您可以使用该callback()表单进行编码并自行Promise包装,以按照您的期望进行操作。

再次指出,需要JIRA问题和Triage,这是处理异常的正确方法。但希望很快能解决。同时,从上方选择一种方法。



 类似资料:
  • 我得到的错误是: 线程“main”org . open QA . selenium . web drive异常:Java . net . connect异常:未能连接到localhost/0:0:0:0:0:0:1:14170生成信息:版本:“3.14.0”,修订版:“aacccce0”,时间:“2018-08-02T20:05:20.749Z”系统信息:主机:“D790-18”,IP:“192

  • 这是我在运行上述程序时遇到的错误。有人解决了这个问题吗? 我尝试过改变Selenium和ChromeDriver的版本,但没有任何效果。

  • 我尝试使用TNS URL、用户名和密码连接到Oracle 11i数据库。JNDI正在成功查找数据源,但我无法获得连接。相反,我看到下面的堆栈跟踪。 我的Maven设置如下。 我的Spring MVC应用程序已经部署到Tomcat 8。我的oracle jar文件位于位置。如下所示 我的web.xml配置 我不确定我做错了什么。我能够使用DriverManager API成功连接。我看了下面的帖子,

  • 我正在使用Firefox 47.0.1和木偶驱动程序geckodriver-v0。8.0-win32。但我遇到了无法访问的浏览器异常,无法打开。 我的代码片段如下所示: 将异常显示为:- 组织。openqa。硒。遥远的UnreachableBrowserException:无法启动新会话。可能的原因是远程服务器地址无效或浏览器启动失败。构建信息:版本:'2.53.0',版本:'35ae25b',时

  • 我使用Firefox驱动程序编写了许多Selenium测试,效果很好。但由于某些原因,我现在在尝试实例化Firefox驱动程序时遇到了一个异常。有人知道Firefox的任何更新可能会影响这一点吗? 下面是两行代码。异常发生在第2行:- 以下是我得到的例外情况:- “WebDriver.dll中出现“OpenQA.Selenium.WebDriverException”类型的异常,但未在用户代码中处

  • 问题内容: 我正在使用此链接制作一些docker- compose yml文件。在此配置中,顶层卷中的driver:local的含义是什么? 问题答案: 它是音量驱动程序,相当于 表示esdata1和esdata2卷是在运行容器的同一Docker主机上创建的。通过使用其他Volume插件,例如 您可以在外部主机上创建卷并将其装入本地主机,例如。因此,当您的容器写入时,它实际上是通过网络写入外部磁盘