83

I have some tests - namely Supertest - that load my Express app. This app creates a Mongoose connection. I would like to know how to check the status of that connection from within my test.

In app.js

mongoose.connect(...)

In test.js

console.log(mongoose.connection.readyState);

How to access the app.js connection? If I connect using the same parameters in test.js will that create a new connection or look for existing one?

cyberwombat
  • 38,105
  • 35
  • 175
  • 251
  • 1
    are both scripts running independent from each other or is test.js required by app.js? – Bernhard Oct 25 '13 at 21:23
  • @Bernhard the test.js requires app.js - in app.js I do var app = exports.app = express() and in test I do require('../app.js').app – cyberwombat Oct 26 '13 at 00:46

4 Answers4

203

Since the mongoose module exports a singleton object, you don't have to connect in your test.js to check the state of the connection:

// test.js
require('./app.js'); // which executes 'mongoose.connect()'

var mongoose = require('mongoose');
console.log(mongoose.connection.readyState);

ready states being:

  • 0: disconnected
  • 1: connected
  • 2: connecting
  • 3: disconnecting
HongboZhu
  • 4,442
  • 3
  • 27
  • 33
robertklep
  • 198,204
  • 35
  • 394
  • 381
  • 48
    Output - 0 = disconnected, 1 = connected, 2 = connecting, 3 = disconnecting [(soucre)](http://mongoosejs.com/docs/api.html#connection_Connection-readyState) My credentials were invalid, it was giving 4, which I can't find in officials docs or anywhere else. – Ashwani Agarwal Feb 12 '16 at 07:40
  • 8
    @AshwaniAgarwal check out [this file](https://github.com/Automattic/mongoose/blob/4237515684bbab8401e579125f2a3b204765bd83/lib/connectionstate.js). – robertklep Feb 12 '16 at 07:48
  • 1
    Best solutions I found to check connection state on every request. I've put it in a middleware to propagate DB connection errors to client – Tdy Aug 17 '16 at 06:03
  • 2
    If the MongoDB is stopped/crashsed, the state still remains the same. In my case, if it is 1 when connected and if mongo is stopped, it is still printing 1. – Ravi Kumar Gupta Nov 01 '17 at 09:24
  • 2
    @RaviKumarGupta it may take (quite) some time before Mongoose knows that the connection has been broken. – robertklep Nov 01 '17 at 09:59
  • 3
    @robertklep, I thought so. I tried printing the ready state after mongo was shut down. I could still see readyState value as 1 even after 5 minutes.. :( – Ravi Kumar Gupta Nov 08 '17 at 12:50
8

I use this for my Express Server mongoDB status, where I use the express-healthcheck middleware

// Define server status
const mongoose = require('mongoose');
const serverStatus = () => {
  return { 
     state: 'up', 
     dbState: mongoose.STATES[mongoose.connection.readyState] 
  }
};
//  Plug into middleware.
api.use('/api/uptime', require('express-healthcheck')({
  healthy: serverStatus
}));

Gives this in a Postman request when the DB is connected.

{
  "state": "up",
  "dbState": "connected"
}

Gives this response when the database was shutdown.

{
"state": "up",
"dbState": "disconnected"
}

(The "up" in the responses represent my Express Server status)

Easy to read (no numbers to interpret)

englishPete
  • 809
  • 10
  • 15
3

As stated before "readyState" is good. "ping" is also good admin utility for doing so as well. It will return { ok: 1 } if it can accept commands.

const mongoose = require('mongoose')

// From where ever your making your connection
const connection = await mongoose.createConnection(
    CONNECT_URI,
    CONNECT_OPTS
)

async function connectionIsUp(): Promise<boolean> {
    try {
        const adminUtil = connection.db.admin()

        const result = await adminUtil.ping()

        console.log('result: ', result) // { ok: 1 }
        return !!result?.ok === 1
    } catch(err) {
        return false
    }    
} 

Or if you you want it short.

async function connectionIsUp(): Promise<boolean> {
    try {
        return await connection.db.admin().ping().then(res => !!res?.ok === 1)
    } catch (err) {
        return false
    }
}
Mardok
  • 1,360
  • 10
  • 14
1
var dbState = [{
    value: 0,
    label: "disconnected"
},
{
    value: 1,
    label: "connected"
},
{
    value: 2,
    label: "connecting"
},
{
    value: 3,
    label: "disconnecting"
}];

mongoose.connect(CONNECTIONSTRING, {
    useNewUrlParser: true
},
() => {
    const state = Number(mongoose.connection.readyState);
    console.log(dbState.find(f => f.value == state).label, "to db"); // connected to db
});