我意识到这似乎是其他问题的重复,但是在发布此问题之前,我已经查看了我可以找到的每个建议的SO问题,并且我正在此特定情况下寻求帮助,因为其他答案均无济于事对我来说。
我有一个Node / Express应用程序,该应用程序正在初始化要由REST API使用的单个MongoDB连接。第一步是连接到MongoDB实例。如果初始连接失败,它将按预期抛出错误。我正在使用async / await及其内部的try / catch块来处理它。我到过的所有地方都说,这足以捕获这些异步/等待的诺言拒绝,但是无论我在哪里.catch()
或尝试/捕获我的代码,我都始终遇到关于UnhandledPromiseRejection的错误(如建议在其他SO帖子中。)
例如,在此链接中,我有与错误处理部分所述的内容几乎相同的东西,但问题仍然存在。
https://javascript.info/async-await
这是错误(我知道是什么导致了错误本身-我现在已经停止了MongoDB服务-但我正在尝试解决未处理的承诺拒绝错误):
(node:15633) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:15633) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:13802) UnhandledPromiseRejectionWarning: MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]
at Pool.<anonymous> (/home/allen/scripts/lysi/eosMain/node_modules/mongodb-core/lib/topologies/server.js:562:11)
at Pool.emit (events.js:189:13)
at Connection.<anonymous> (/home/allen/scripts/lysi/eosMain/node_modules/mongodb-core/lib/connection/pool.js:316:12)
at Object.onceWrapper (events.js:277:13)
at Connection.emit (events.js:189:13)
at Socket.<anonymous> (/home/allen/scripts/lysi/eosMain/node_modules/mongodb-core/lib/connection/connection.js:245:50)
at Object.onceWrapper (events.js:277:13)
at Socket.emit (events.js:189:13)
at emitErrorNT (internal/streams/destroy.js:82:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
at process._tickCallback (internal/process/next_tick.js:63:19)
这是我的代码:
exports.mongoConnect = async (dbName, archiveDbName, userName, password) => {
// Auth params
const user = encodeURIComponent(userName);
const pass = encodeURIComponent(password);
const authMechanism = 'DEFAULT';
// Connection URL
const url = `mongodb://${user}:${pass}@localhost:27017?authMechanism=${authMechanism}&authSource=admin`;
let client;
try {
// Use connect method to connect to the Server
client = await MongoClient.connect(url, { useNewUrlParser: true, poolSize: 10, autoReconnect: true, reconnectTries: 6, reconnectInterval: 10000 }).catch((e) => { console.error(e) });
db = client.db(dbName);
archiveDb = client.db(archiveDbName);
console.log(`Succesfully connected to the MongoDb instance at URL: mongodb://localhost:27017/ with username: "` + client.s.options.user + `"`);
console.log(`Succesfully created a MongoDb database instance for database: "` + db.databaseName + `" at URL: mongodb://localhost:27017/`);
console.log(`Succesfully created a MongoDb database instance for database: "` + archiveDb.databaseName + `" at URL: mongodb://localhost:27017/`);
} catch (err) {
console.log(`Error connecting to the MongoDb database at URL: mongodb://localhost:27017/` + dbName);
}
}
像这样从app.js调用的:
mongoUtil.mongoConnect('myDb', 'myArchiveDb', 'myUser', 'myPassword');
我什至尝试将这一行放在try / catch块中,或者将诺言样式.catch()
添加到它的末尾,而无需进行任何更改。
我似乎无法弄清为什么它仍然抱怨没有处理承诺拒绝。
编辑:
这是整个app.js文件:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var cors = require('cors');
var app = express();
const MongoClient = require('mongodb').MongoClient;
// This is where the mongo connection happens
var mongoUtil = require( './services/mongoUtil' );
var bluebird = require('bluebird');
const jwt = require('./helpers/jwt');
var api = require('./routes/api.route')
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/api', api);
// use JWT auth to secure the api
app.use(jwt());
app.use('/users', require('./users/users.controller'));
MongoClient.Promise = bluebird
mongoUtil.mongoConnect('myDb', 'myArchiveDb', 'username', 'password');
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
next();
});
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;`
答案 0 :(得分:0)
答案 1 :(得分:0)
您正在以同步方式从app.js
调用connect,因此您的async/await
方法将不起作用。您可以使用sleep
函数对其进行测试:
let sleep = () => {
return new Promise(function(resolve, reject) {
setTimeout(function(){
console.log('Finished sleeping');
resolve();
}, 2000)
})
}
exports.mongoConnect = async (dbName, archiveDbName, userName, password) => {
await sleep() // sleep two seconds
// rest of your mongoConnect code
})
然后在连接后在app.js
中添加一个日志:
mongoUtil.mongoConnect('myDb', 'myArchiveDb', 'username', 'password');
console.log('Finished connection');
您将在控制台中获得以下输出:
Finished connection // You can see the code doesnt wait to mongo to connect
[After 2 seconds]
Finished sleeping // After this sleep log it will start connecting...
要解决此问题,您需要以异步方式执行app.js
:
请注意,不建议使用顶级异步功能,但我希望您看到此错误
(async () => {
// rest of your app.js
await mongoUtil.mongoConnect('myDb', 'myArchiveDb', 'username', 'password');
console.log('Finished connection attempt');
// rest of your app.js
})()
然后我在控制台遇到的错误是(无警告!):
{ MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]
at Pool.<anonymous> (/node_modules/mongodb-core/lib/topologies/server.js:564:11)
at Pool.emit (events.js:182:13)
at Connection.<anonymous> (/node_modules/mongodb-core/lib/connection/pool.js:317:12)
at Object.onceWrapper (events.js:273:13)
at Connection.emit (events.js:182:13)
at Socket.<anonymous> (/node_modules/mongodb-core/lib/connection/connection.js:246:50)
at Object.onceWrapper (events.js:273:13)
at Socket.emit (events.js:182:13)
at emitErrorNT (internal/streams/destroy.js:82:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
at process._tickCallback (internal/process/next_tick.js:63:19)
name: 'MongoNetworkError',
errorLabels: [ 'TransientTransactionError' ],
[Symbol(mongoErrorContextSymbol)]: {} }
Error connecting to the MongoDb database at URL: mongodb://localhost:27017/myDb
Finished connection attempt