Catch 在连接到 Mongo 时失败 [英] Catch fails on connection to Mongo

查看:42
本文介绍了Catch 在连接到 Mongo 时失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题的答案:How当 mongo 连接失败时让节点退出 包含连接的异步/等待代码

the answer to this question: How to get node to exit when mongo connect fails contains async/wait code for a connection

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

however, my code (running on node v11.5.0 and mongodb v3.1.13) is failing to catch:

(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:

to prove the point I intentionally give a uri without credentials:

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

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

我得到的是这样的输出:

and what I get is output like this:

/Users/ekkis/dev/mongo/node_modules/mongodb/lib/topologies/replset.js:346抛出错误;^

/Users/ekkis/dev/mongo/node_modules/mongodb/lib/topologies/replset.js:346 throw err; ^

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)在 authenticationLiveConnections (/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)在 auth (/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)

MongoError: password must be a string at passwordDigest (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/auth/scram.js:63:43) at ScramSHA1.ScramSHA.auth (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/auth/scram.js:175:25) at authenticate (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/connection/pool.js:232:17) at authenticateLiveConnections (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/connection/pool.js:819:7) at /Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/connection/pool.js:864:5 at waitForLogout (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/connection/pool.js:855:34) at Pool.auth (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/connection/pool.js:862:3) at Server.auth (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/topologies/server.js:931:20) at auth (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/topologies/replset.js:1474:19) at ReplSet.auth (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/topologies/replset.js:1492:5)

所以如果错误被捕获,控制台应该显示退出"这个词,但没有.另外,我认为抛出了一个异常,因为否则返回的值会被打印出来,而不是

so if the error had been caught, the console should have displayed the word 'EXITING', but does not. additionally, I contend an exception was thrown because otherwise the returned value would have been printed, which it was not

这怎么可能?我需要做什么才能让它工作?

how can this be? what do I need to do to get it to work?

* 附录 I *

事实上,promise 版本也表现出同样奇怪的行为,它没有捕获:

In fact, the promises version of this exhibits the same odd behaviour, it doesn't catch:

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

是的,我测试了回调版本,它也有同样的问题.顺便说一句,为 uri 传递一个空字符串效果很好.没看懂

and yes, I tested the callback version, which also suffers the same malady. Incidentally, passing an empty string for the uri works well. I don't get it

* 附录二 *

事实上,问题似乎与传递的凭据有关,即如果我通过:

In fact, the problem seems to be particular to the credentials passed i.e. if I pass:

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

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

我按预期捕获了MongoError:身份验证失败".路过:

I catch a "MongoError: authentication fail" as expected. passing:

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

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

有趣的是返回一个连接但缺少:"的凭据以这种奇怪的方式失败,因此:

interestingly returns a connection but credentials missing a ":" fail in this odd way, so:

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

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

未能抓住

推荐答案

在我看来这是一个错误,但是 MongoClient 正在设置其连接.您将无法使用 try &catch 处理 MongoClient 代码中异步抛出的错误.

Looks to me like it's a bug with however MongoClient is setting up its connections. You won't be able to use try & catch to handle asynchronously thrown errors within MongoClient code.

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 处理程序捕获

Here's a simplified example of what's happening -- the error will end up "uncaught" and caught by the uncaughtException handler

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")
}

这篇关于Catch 在连接到 Mongo 时失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆