Ваш код «работает», если соединение с БД устанавливается впервые.
Если используется механизм повтора, вы увидите описанную ошибку.
Promise
создается при первом вызове mongoDBConnect
никогда не разрешается в пути выполнения повторных попыток.
Это происходит потому, что последующие вызовы mongoDBConnect
выполняются в совершенно отдельном контексте выполнения в будущем тике события l oop, управляемый setTimeout
- и каждый вызов создает новую Promise
, полностью отключенную от вашей connect
функции.
Этот рефакторинг должен решить проблему:
const delay = (interval) => new Promise(resolve => setTimeout(resolve, interval))
async connect() {
const options = {...}
try {
console.log("starting")
await this._connectWithRetry(options)
console.log("finished")
} catch (err) {
winston.error(`Could not connect to Mongo with error: ${err}`)
}
}
private async _connectWithRetry(options) {
try {
winston.info("Connecting to mongo...")
await mongoose.connect(this.dbURI, options)
winston.info("Connection successful.")
} catch (err) {
winston.info("Failed to connect to mongo. Retrying in 5 seconds...")
await delay(5000)
await this._connectWithRetry(options)
}
}
Испытательный жгут:
let retryCount = 0
const mongoose = {
connect: ()=>retryCount++ === 2 ? Promise.resolve() : Promise.reject('fake error')
}
async function connect() {
try {
console.log("starting")
await connectWithRetry()
console.log("finished")
} catch (err) {
console.error(`connect error`, err)
}
}
async function connectWithRetry() {
try {
console.log("Connecting to mongo...")
await mongoose.connect()
console.log("Connection successful.")
} catch (err) {
console.log("Retrying in 1 second...", err)
await delay(1000)
await connectWithRetry()
}
}
const delay = (interval) => new Promise(resolve => setTimeout(resolve, interval))
connect()