连接到Mongo时捕获失败

时间:2019-02-17 20:16:04

标签: node.js mongodb try-catch

此问题的答案:How to get node to exit when mongo connect fails包含连接的异步/等待代码

但是,我的代码(在节点v11.5.0和mongodb v3.1.13上运行)无法捕获:

(async function() {
  let db; 
  try {
    db = await MongoClient.connect(uri, { useNewUrlParser: true }); 
    console.log("RETURN", db);
  } catch (err) {
    console.log('EXITING');
    process.exit(1);
  }
}());

为了证明这一点,我有意提供了没有凭据的uri:

  

mongodb://undefined@cluster0-shard-00-00-z4j9e.azure.mongodb.net:27017,cluster0-shard-00-01-z4j9e.azure.mongodb.net:27017,cluster0-shard-00 -02-z4j9e.azure.mongodb.net:27017/test?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin&retryWrites=true

我得到的是这样的输出:

  

/用户/ekkis/dev/mongo/node_modules/mongodb/lib/topologies/replset.js:346      犯错      ^

     

MongoError:密码必须为字符串       在passwordDigest(/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/auth/scram.js:63:43)       在ScramSHA1.ScramSHA.auth(/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/auth/scram.js:175:25)       在验证时(/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/connection/pool.js:232:17)       在authenticateLiveConnections(/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/connection/pool.js:819:7)       在/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/connection/pool.js:864:5       在waitForLogout(/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/connection/pool.js:855:34)       在Pool.auth(/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/connection/pool.js:862:3)       在Server.auth(/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/topologies/server.js:931:20)       在身份验证(/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/topologies/replset.js:1474:19)       在ReplSet.auth(/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/topologies/replset.js:1492:5)

因此,如果已捕获错误,则控制台应该显示单词“ EXITING”,但不会显示。另外,我认为抛出了异常,因为否则将打印返回的值,而不是

怎么可能?我需要怎么做才能使其正常工作?

*附录I *

实际上,此承诺版本具有相同的奇怪行为,但不能捕获:

MongoClient
  .connect(uri, { useNewUrlParser: true })
  .then(dbc => {
    console.log('SUCCESS');
    })
  .catch(err => {
    console.log('EXITING');
    process.exit(1);
  });

是的,我测试了回调版本,该版本也遭受了同样的疾病。顺便说一句,为uri传递一个空字符串很有效。我不明白

*附录II *

实际上,问题似乎是通过的凭据所致,即如果我通过了:

  

mongodb:// x:y @ cluster0-shard- [...]

我按预期捕获了“ MongoError:身份验证失败”。通过:

  

mongodb:// @ cluster0-shard- [...]

有趣地返回一个连接,但是缺少“:”的凭据以这种奇怪的方式失败,所以:

  

mongodb:// ekkis @ cluster0-shard- [...]

未能赶上

2 个答案:

答案 0 :(得分:1)

在我看来,这是一个错误,但是MongoClient正在设置其连接。您将无法使用trycatch处理MongoClient代码中的异步引发的错误。

const {MongoClient} = require("mongodb");

process.on("uncaughtException", (err) => {
  console.log("process err", err);
  process.exit(1)
})

async function run () {
  let db;
  try {
    // connection url will throw because password isn't provided
    db = await MongoClient.connect("mongodb://myUsername:@localhost", { useNewUrlParser: true }); 
  } catch (err) {
    console.log('Exiting from thrown error', err);
    process.exit(1);
  }
}

run();

这是正在发生的事情的简化示例-错误最终将“未捕获”并由uncaughtException处理程序捕获

process.on("uncaughtException", (err) => console.log("uncaught", err));
try {
  setTimeout(() => {
    throw new Error("asynchronously thrown error");
  })
} catch (err) {
  console.log("Error will not be caught here")
}

答案 1 :(得分:0)

当我使用mongo版本3.6.1时,这不是问题,我能够使用catch处理抛出的异常。但是在另一个项目上运行了几天后,这种类型的错误发生了,并显示为由

引发的错误
%project_folder%/node_modules/mongodb/lib/utils.js:668

(不要介意路径字符串中的斜线。) 这次的mongodb版本是3.6.3。在上述行中检查该文件中的代码后,我发现了以下代码。再次引发捕获的错误。

fn(function(err, res) {
   if (err != null) {
   try {
     callback(err);
   } catch (error) {
     return process.nextTick(() => {
      throw error;
     });
    }
    return;
  }
 callback(err, res);
});

我将throw error更改为console.error(error),问题得到解决。但是仍然需要在我们的代码中某个地方调用connect函数。

我认为这是因为上面的代码正在检查错误的存在并将其传递给回调函数,然后再次引发相同的错误。我认为解决此问题是MongoDB驱动程序开发人员社区的责任。