キャッチハンドラーでmongoose.connect()
エラーを処理するにmongoose.connect()
が拒否されたpromiseを返さないため、使用できません。 コールバックを指定した場合にのみ拒否されたpromiseが返されますが、完全な解決策ではありません。
例:
mongoose.connect('mongodb://127.0.0.2/test') // if error it will throw async error
.then(() => { // if all is ok we will be here
return server.start();
})
.catch(err => { // we will not be here...
console.error('App starting error:', err.stack);
process.exit(1);
});
回避策:
mongoose.connect('mongodb://127.0.0.2/test', function() { /* dummy function */ })
.then(() => {
return server.start();
})
.catch(err => { // mongoose connection error will be handled here
console.error('App starting error:', err.stack);
process.exit(1);
});
mongoose.connect()
は、下位互換性を壊さないために、拒否されたpromiseを返す代わりに非同期エラーをスローすると思います。 ユーザーは、マングース接続の確立で問題が発生した場合、アプリケーションがエラーコードで終了することを期待しています。 mongoose.connect()
が拒否された場合、promiseアプリケーションは0コードで終了し、コンソールには何も出力されません。 したがって、約束を返すためにmongoose.connect()
と言う方法があるとよいでしょう。 たぶんexec()
ようなもの:
mongoose.connect('mongodb://127.0.0.2/test').exec()
.then(() => { // if all is ok we will be here
return server.start();
})
.catch(err => { // if error we will be here
console.error('App starting error:', err.stack);
process.exit(1);
});
mongoose.connect('mongodb://localhost/dbCollection', function(err, db) {
if (err) {
console.log('Unable to connect to the server. Please start the server. Error:', err);
} else {
console.log('Connected to Server successfully!');
}
});
@ nasr18どういう意味ですか? :smiley:コールバックを使いたくない)
@Jokeroごめんなさい男.........あなたの質問を誤解しました。 :)
接続中のエラーをキャッチするには、mongoose.connectのコールバックを使用します。
イベントが開いたときにサーバーを起動できます。
mongoose.connection.once('open', function() {
logger.info('MongoDB event open');
logger.debug('MongoDB connected [%s]', url);
mongoose.connection.on('connected', function() {
logger.info('MongoDB event connected');
});
mongoose.connection.on('disconnected', function() {
logger.warn('MongoDB event disconnected');
});
mongoose.connection.on('reconnected', function() {
logger.info('MongoDB event reconnected');
});
mongoose.connection.on('error', function(err) {
logger.error('MongoDB event error: ' + err);
});
// return resolve();
return server.start();
});
return mongoose.connect(url, options, function(err) {
if (err) {
logger.error('MongoDB connection error: ' + err);
// return reject(err);
process.exit(1);
}
});
@mathieug私は知っています、エラー処理にコールバックを使用できますが、問題は約束に関するものです:smiley:
mongoose.connectからのpromiseを使用せず、接続が初めて開いたときにサーバーを起動します(.once( 'open'))
どうして? まったく違いはありません。 接続が開かれると、 mongoose.connect
コールバックが呼び出され、返されたpromiseが実行され、 open
イベントが発行されます。 だからあなたはあなたが望むものを使うことができます
はい、しかしあなたが言ったように、mongoose.connectはエラーの場合にコールバックを必要とします。
だから私はこの問題を作成しました:smiley:
同じ問題があります。
mongoose.connect(...).catch(failCallback)
を使用できるようにしたいのですが、最初の接続試行時にエラーが発生すると、 failCallback
が実行されません。 mongoose.connect
が返されるというMongooseThenable
疑似約束に何か問題があります。 さらに、私はmongoose.Promise = require('bluebird')
を設定しましたが、そのような非同期呼び出しが_real_promise(私の場合はBluebird)を返すことを本当に期待しています。
ただし、 failCallback
が実行されないという問題は、最初にのみ発生します。
// First kill mongod instance so that Mongoose cannot connect and start the app
mongoose.connect(uri, options).catch(failCallback); // failCallback does _not_ get called
// Then stop the app, start mongod instance so that Mongoose can connect, start the app
mongoose.connect(uri, options).then(successCallback); // successCallback gets called
// Then kill mongod instance so that Mongoose disconnects (while the app is running)
mongoose.connection.on('disconnected', function () {
setTimeout(function () {
mongoose.connect(uri, options).catch(reconnectFailCallback); // now reconnectFailCallback _does_ get called
}, randomDelayOfAboutASecond);
});
しかし、実際にはそのように機能します(これは無意味です):
// First kill mongod instance so that Mongoose cannot connect and start the app
var dummyNoopCallback = function () {};
mongoose.connect(uri, options, dummyNoopCallback).catch(failCallback); // failCallback _does_ get called
何故ですか?
Re:本当の約束を返す、それは下位互換性のためのその方法です。 残念ながら、人々は何らかの理由(#3847、#3790など)で.connect()
チェーン動作に依存しているため、今のところこの方法を維持しています:) .catch()
が初期接続をキャッチできるように修正を追加しました問題。
できます! しかし、これらの変更は、接続エラーが発生し、コールバックとプロミスのハンドラーがないときにアプリケーションプロセスが終了することを期待している人にとって、何かを壊しますか?
例:
const mongoose = require('mongoose');
mongoose.Promise = Promise;
mongoose.connect('mongodb://127.0.0.2/test'); // no callback and promise handlers
これらの変更前
/home/dmitry/example/node_modules/mongodb/lib/server.js:242
process.nextTick(function() { throw err; })
^
Error: connect ECONNREFUSED 127.0.0.2:27017
at Object.exports._errnoException (util.js:870:11)
at exports._exceptionWithHostPort (util.js:893:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1057:14)
これらの変更により、プロセスは0コードで終了します
提案をありがとう、調査します。
涼しい! ありがとう:+1:
+1
.connect()の結果を、初期化チェーンの本格的なPromiseとして返すことができるようにしたいと考えています。
@CodeJjangこれはまだ機能していませんか? この機能はすでにリリースされています
mongoose.connect('mongodb://127.0.0.2/test', function() { /* dummy function */ })
.then(() => {
return server.start();
})
.catch(err => { // mongoose connection error will be handled here
console.error('App starting error:', err.stack);
process.exit(1);
});
これは私にはうまくいきません:(
それは示しています(node:22564) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): MongoError: failed to connect to server [127.0.0.1:27017] on first connect
うーん、 mongoose.connect()
コールバックを取り除いてみてください
私はちょうど得た:
UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1):
MongoError: failed to connect to server [localhost:17551] on first connect
マングース4.7.6(現在最新)でpromiseを使用していない場合、その警告を回避する方法はありますか?
ExpressJSで使用していますが、catchを使用すると、ロジックがねじ込まれ、 express-session
がMongoStoreも作成しているため、奇妙な動作をします...ただ面倒です。
コードサンプルをお願いします
@matheoと同じ問題があります。 このチケットを開いたところ:
後で来る人を確認するために、これは期待どおりに機能します。
mongoose.connect('http://127.0.0.1:27017/test')
.then(() => {
server.start();
})
.catch((err) => {
console.log('Error on start: ' + err.stack);
process.exit(1);
});
後で来る人を確認するために、これは期待どおりに機能します。
mongoose.connect('http://127.0.0.1:27017/test') .then(() => { server.start(); }) .catch((err) => { console.log('Error on start: ' + err.stack); process.exit(1); });
私もこのアプローチを使用しています! しかし、mongodbを停止してからこのコードを実行すると、機能しません。
// mongoose version 5.4.14
mongoose
.connect(databaseUri, {
promiseLibrary: bluebird,
useNewUrlParser: true,
useFindAndModify: false,
useCreateIndex: true,
// Automatically try to reconnect when it loses connection to MongoDB
autoReconnect: true,
// Never stop trying to reconnect
reconnectTries: Number.MAX_VALUE,
// Reconnect every 500ms
reconnectInterval: 500,
// Maintain up to 10 socket connections. If not connected,
// return errors immediately rather than waiting for reconnect
poolSize: 10,
// Give up initial connection after 10 seconds
connectTimeoutMS: 10000,
})
.catch((err) => {
console.log(err);
process.exit(1);
});
@ nvtuan305 「機能しない」とはどういう意味ですか? エラーメッセージはありますか?
@ vkarpov15エラーが出力されないことを意味します
手順:
catch
ブロックに到達しません。 // Never reach to here
console.log(err);
process.exit(1);
@ nvtuan305初期接続がmongooseはconnectTimeoutMS
後にエラーを報告します。 そうではありませんか? もしそうなら、MongoDBとmongooseのどのバージョンですか?
@ vkarpov15
マングースは
connectTimeoutMS
後にエラーを報告します
私の場合、mongooseはcatch
ブロックのconnectTimeoutMS
後にエラーを報告しません。 私はMongodb3.6.5とmongoose5.4.14を使用しています
> mongod --version
db version v3.6.5
git version: a20ecd3e3a174162052ff99913bc2ca9a839d618
OpenSSL version: OpenSSL 1.0.2p 14 Aug 2018
allocator: system
modules: none
build environment:
distarch: x86_64
target_arch: x86_64
@ nvtuan305確認のために、スタンドアロンのmongodbインスタンスまたはレプリカセットに接続していますか?
@ vkarpov15スタンドアロンインスタンスを使用しています。
@ nvtuan305どのオペレーティングシステムですか? また、なぜMongooseがスタンドアロンへの接続に失敗すると予想するのですか? mongod
インスタンスがダウンしているのか、ネットワーク接続がないのか、他に何かありますか?
以下のスクリプトは期待どおりに機能します。
const assert = require('assert');
const mongoose = require('mongoose');
mongoose.set('debug', true);
run().then(() => console.log('done')).catch(error => console.error(error.stack));
async function run() {
console.log(mongoose.version);
const start = Date.now();
const opts = { useNewUrlParser: true, connectTimeoutMS: 1000 };
await mongoose.connect('mongodb://doesntexist.com:27017/test', opts).
catch(error => { console.log(`Caught "${error.message}" after ${Date.now() - start}`); });
}
出力
$ node gh-4135.js
5.4.14
Caught "failed to connect to server [doesntexist.com:27017] on first connect [MongoNetworkError: connection 0 to doesntexist.com:27017 timed out]" after 1024
done
$ ^C
ねえ、それは基本的なようですが、これらの指示を再確認してください
私はそれをやって解決します
最も参考になるコメント
後で来る人を確認するために、これは期待どおりに機能します。