Wie behandelt man den mongoose.connect()
Fehler im Catch-Handler? Ich möchte die Anwendungsinitialisierungskette verwenden, kann dies jedoch nicht, da mongoose.connect()
kein abgelehntes Versprechen zurückgibt. Es gibt nur abgelehnte Zusagen zurück, wenn ich Rückruf angebe, aber es ist keine perfekte Lösung.
Beispiel:
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);
});
Problemumgehung:
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);
});
Ich denke, mongoose.connect()
löst einen asynchronen Fehler aus, anstatt ein abgelehntes Versprechen zurückzugeben, um die Abwärtskompatibilität nicht zu beeinträchtigen. Benutzer erwarten, dass die Anwendung mit einem Fehlercode beendet wird, wenn bei der Herstellung der Mungo-Verbindung etwas schief gelaufen ist. Wenn mongoose.connect()
abgelehnte Zusage zurückgibt, wird die Anwendung mit 0-Code beendet und es wird nichts an die Konsole ausgegeben. Es ist also gut, eine Möglichkeit zu haben, mongoose.connect()
zu sagen, um das Versprechen zurückzugeben. Vielleicht so etwas wie 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 Was meinst du? :smiley: Ich möchte keinen Rückruf verwenden)
@Jokero Entschuldigung, Alter......... habe deine Frage falsch verstanden. :)
Verwenden Sie den Rückruf von mongoose.connect, um Fehler während der Verbindung abzufangen.
Sie können Ihren Server im Ereignis öffnen starten.
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 Ich weiß, ich kann Callback für die Fehlerbehandlung verwenden, aber das Problem
Verwenden Sie nicht das Versprechen von mongoose.connect, starten Sie Ihren Server, wenn die Verbindung zum ersten Mal geöffnet ist (.once('open'))
Wieso den? Überhaupt kein Unterschied. Wenn die Verbindung geöffnet wird, wird mongoose.connect
Callback aufgerufen, sowie das zurückgegebene Versprechen erfüllt und open
Event ausgegeben. Du kannst also verwenden, was du willst
Ja, aber wie gesagt, mongoose.connect braucht im Fehlerfall einen Rückruf.
Deshalb habe ich dieses Problem erstellt :smiley:
Ich habe das gleiche Problem.
Ich möchte mongoose.connect(...).catch(failCallback)
aber wenn beim ersten Verbindungsversuch ein Fehler auftritt, wird failCallback
nicht ausgeführt. Etwas stimmt nicht mit dem MongooseThenable
Pseudoversprechen, das mongoose.connect
zurückgibt. Außerdem habe ich mongoose.Promise = require('bluebird')
konfiguriert und ich erwarte wirklich, dass solche asynchronen Aufrufe ein _echtes_ Versprechen zurückgeben, in meinem Fall ein Bluebird-Versprechen.
Das Problem, dass mein failCallback
nicht ausgeführt wird, tritt jedoch nur anfänglich auf, dh:
// 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);
});
Aber es funktioniert tatsächlich so (was unsinnig ist):
// 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
Warum ist das so?
Re: Ein echtes Versprechen zurückgeben, es ist so für die Abwärtskompatibilität. Leider Menschen verlassen sich auf .connect()
aus irgendeinem Grunde Verhalten Chaining (# 3847, # 3790, etc.) , so dass wir es auf diese Weise für jetzt halten sind :) Hinzugefügt ein Update so .catch()
können anfängliche Verbindung fangen Probleme.
Es klappt! Aber werden diese Änderungen etwas für diejenigen bedeuten, die erwarten, dass der Bewerbungsprozess abgeschlossen ist, wenn ein Verbindungsfehler auftritt und es keine Callback- und Promise-Handler gibt?
Beispiel:
const mongoose = require('mongoose');
mongoose.Promise = Promise;
mongoose.connect('mongodb://127.0.0.2/test'); // no callback and promise handlers
Vor diesen Änderungen
/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)
Mit diesen Änderungen ist der Vorgang mit 0 Code abgeschlossen
Danke für den Vorschlag, werde nachforschen.
Cool! Danke :+1:
+1
Würde gerne das Ergebnis von .connect() als vollwertiges Promise in der Initialisierungsverkettung zurückgeben.
@CodeJjang funktioniert das nicht schon? Diese Funktion wurde bereits freigegeben
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);
});
Das funktioniert bei mir nicht :(
Es zeigt
(node:22564) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): MongoError: failed to connect to server [127.0.0.1:27017] on first connect
Hmm, versuchen Sie, den Rückruf in mongoose.connect()
loszuwerden
Ich habe gerade:
UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1):
MongoError: failed to connect to server [localhost:17551] on first connect
keine Versprechungen für Mungo 4.7.6 (aktuell aktuell) verwenden, gibt es eine Möglichkeit, diese Warnung zu vermeiden?
Ich verwende es mit ExpressJS und wenn ich catch verwende, verdreht es meine Logik und verhält sich seltsam, da express-session
einen MongoStore erstellt ... einfach chaotisch.
Codebeispiel bitte
Ich habe das gleiche Problem wie @matheo. Habe gerade dieses Ticket geöffnet:
Nur zur Bestätigung für alle, die später kommen, funktioniert dies wie erwartet:
mongoose.connect('http://127.0.0.1:27017/test')
.then(() => {
server.start();
})
.catch((err) => {
console.log('Error on start: ' + err.stack);
process.exit(1);
});
Nur zur Bestätigung für alle, die später kommen, funktioniert dies wie erwartet:
mongoose.connect('http://127.0.0.1:27017/test') .then(() => { server.start(); }) .catch((err) => { console.log('Error on start: ' + err.stack); process.exit(1); });
Diesen Ansatz verwende ich auch! Aber wenn ich mongodb beende und dann diesen Code ausführe, funktioniert es nicht.
// 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 was meinst du mit "funktioniert nicht"? Gibt es einige Fehlermeldungen?
@vkarpov15 Ich meine, es wird kein Fehler gedruckt
Verfahren:
catch
Block wird nicht erreicht. // Never reach to here
console.log(err);
process.exit(1);
@nvtuan305 Wenn die anfängliche Verbindung connectTimeoutMS
einen Fehler. Ist das bei Ihnen nicht der Fall? Wenn ja, welche Version von MongoDB und Mongoose?
@vkarpov15
Mungo meldet einen Fehler nach
connectTimeoutMS
In meinem Fall meldet Mungo keinen Fehler nach connectTimeoutMS
im catch
Block. Ich verwende Mongodb 3.6.5 und Mungo 5.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 nur zur Bestätigung, stellen Sie eine Verbindung zu einer eigenständigen Mongodb-Instanz oder einem Replikatsatz her?
@vkarpov15 Ich verwende eine eigenständige Instanz.
@nvtuan305 welches Betriebssystem? Außerdem, warum erwarten Sie, dass Mongoose keine Verbindung zum Standalone-Gerät herstellen kann - ist die Instanz mongod
ausgefallen, besteht keine Netzwerkverbindung oder etwas anderes?
Das folgende Skript funktioniert wie erwartet:
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}`); });
}
Ausgabe
$ 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
Hey, es scheint einfach, aber bitte überprüfen Sie diese Anweisungen noch einmal
Ich löse es damit
Hilfreichster Kommentar
Nur zur Bestätigung für alle, die später kommen, funktioniert dies wie erwartet: