I am trying to connect to to db then run my server. So I am using aync await like below:
startApp = async()=>{
try {
await mongoose.connect('mongodb+srv://tanvirgeek:<password>#cluster0-e7kwf.mongodb.net/test?
retryWrites=true&w=majority',)
console.log('connected to db');
await app.listen(5000);
console.log('server connected on port 5000')
} catch (error) {
console.log(error);
}
}
app.get('/',(req,res)=>{
res.send("hello world");
})
startApp();
I intentionally gave a wrong db connect URL without a password to get error in the console. In the console I am getting no error and this message:server connected on port 5000.
My desired output is error message in the console, without this successful server running message. How can I achieve this?
you are adding a ',' between your path connection and ')'. In mongoose doc:
mongoose.connect('mongodb+srv://tanvirgeek:<password>#cluster0-e7kwf.mongodb.net/test?
retryWrites=true&w=majority', { useNewUrlParser: true }).
catch(error => handleError(error));
// Or:
try {
await mongoose.connect('mongodb+srv://tanvirgeek:<password>#cluster0-e7kwf.mongodb.net/test?
retryWrites=true&w=majority', { useNewUrlParser: true });
} catch (error) {
handleError(error);
}
source mongoose
Related
I have implemented redis cache in my node server.I am running redis docker container locally.I have keys stored in redis container which I am able to see but when I am trying to access then I am failed to get data.
Below is my code:
const redis = require('redis');
let redisClient;
redisClient = redis.createClient('127.0.0.1', 6379);
redisClient.connect();
redisClient.on('error', err => {
console.log('Error ' + err);
});
redisClient.on('connect', () => {
console.log('Connected to Redis');
});
//Saving data here
redisClient.set('Region', 'Asia', (err, reply) => {
if (err) {
console.log('error', err);
}
else {
console.log(reply);
}
});
//Fetching data here
redisClient.get('Region', (err, reply) => {
if (err) {
console.log('error', err);
}
else {
console.log(reply);
}
});
Here even though data is saved successfully in redis but I am not getting console statement after saving data.And I am also unable to fetch data from redis.I am only getting Connected to Redis console log.
Someone let me know what I have done wrong in my code.So far to me code seems fine.
It looks like you are using the node-redis client. In v4, this supports promises. Using promises with async/await should make your code easier to follow:
import { createClient } from 'redis';
try {
const client = createClient();
await client.connect();
await client.set('Region', 'Asia');
const region = await client.get('Region');
console.log(`Region is ${region}`);
await client.quit();
} catch (e) {
console.error('Oh no:');
console.error(e);
}
Following is my snippet of main.ts
try {
process.on('unhandledRejection', (err) => {
// tslint:disable-next-line:no-console
console.error(err); <------- no console
});
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter(),
);
app.enableCors();
app.useGlobalFilters(new AllExceptionsFilter());
await app.listen(3000, () => {
// tslint:disable-next-line:no-console
console.log('listen callback'); <------- no console
}).then(() => {
// tslint:disable-next-line:no-console
console.log('started'); <------- no console
});
} catch (error) {
// tslint:disable-next-line:no-console
console.log('catch', error); <----- only this gets consoled as undefined
}
My app gets connected to database (verified), just that it doesn't start.
Calling .listen() with a callback argument means this method is going to return undefined. You are trying to call .then() on that undefined value.
You need simply need to change your listen call to this:
await app.listen(3000, () => 'Server running on port 3000...');
BONUS: You can test this yourself by setting that call to listen to a variable and then console log it:
const result = await app.listen(3000, () => 'Server running on port 3000...');
console.log(result);
//undefined
I have an Express REST API server written in TypeScript.
At first, I started server like this -
const initServer = async() => {
await connectDb();
await server.listen(secrets.port, secrets.hostname, () => {
logger.info(
`Running server at http://${secrets.hostname}:${secrets.port} in ${
secrets.env
} env and API version is ${secrets.apiVersion}`
);
});
}
initServer().catch(error => logger.error(`Init server went wrong with: ${error}`));
Then I read a blog post suggesting to use .then().catch() -
async function initServer() {
// Connect the database first
await connectDb()
.then(() =>
// then start the server
server.listen(secrets.port, secrets.hostname, () => {
logger.info(
`Running server at http://${secrets.hostname}:${secrets.port} in ${
secrets.env
} env and API version is ${secrets.apiVersion}`
);
})
)
.catch(err => {
logger.error(`Initializing server went wrong with: ${err}`);
process.exit(1);
});
}
Then I read another blog post saying "catch the error first" -
async function initServer() {
// Connect the database first
await connectDb()
// then start the server
.then(() => server.listen(secrets.port, secrets.hostname))
.catch(err => {
logger.error(`Initializing server went wrong with: ${err}`);
process.exit(1);
})
// then announce the server info
.finally(() => {
logger.info(
`Running server at http://${secrets.hostname}:${secrets.port} in ${
secrets.env
} env and API version is ${secrets.apiVersion}`
);
});
}
But I feel like I'm not doing it right. Please educate me what I'm doing wrong.
How should I start the server?
I have created a mongodb native connection and saved it and then using findOne to query a document.
const Promise = require("bluebird");
const MongoClient = require('mongodb').MongoClient;
let mongoDB = undefined;
const getCollection = (collName) => {
if (mongoDB) {
return Promise.resolve(mongoDB.collection(collName));
} else {
return MongoClient.connect(EXT_CONFS.MONGODB_URL)
.then(db => {
mongoDB = db;
return Promise.resolve(mongoDB.collection(collName));
}).catch(e => {
console.error('Error in MongoDb connection');
});
}
};
const findOne = (collName, filter, options) => {
return getCollection(collName)
.then(collection => {
return collection.findOne(filter, options);
})
.then(doc => {
return Promise.resolve(doc);
}).catch(e => {
console.error(e);
return Promise.reject(e);
});
};
Now this all works fine, but if Mongo ShutsDown / Fails after db client is cached, There is no way to handle error. Error never goes to any catch handler :
console.error('Error in MongoDb connection');
or
console.error(e);
I even tried events :
mongoDB.on('connecting', function () {
console.log('connecting');
});
mongoDB.on('timeout', function (error) {
console.log('timeout!');
});
mongoDB.on('close', function (error) {
console.log('close!');
});
mongoDB.on('error', function (error) {
console.error('Error in MongoDb connection: ' + error);
});
mongoDB.on('connected', function () {
console.log('connected!');
});
mongoDB.on('connection', function () {
console.log('connected!');
});
mongoDB.on('connect', function () {
console.log('connected!');
});
mongoDB.once('open', function () {
console.log('connection open');
});
mongoDB.on('reconnected', function () {
console.log('reconnected');
});
mongoDB.on('disconnected', function () {
console.log('disconnected');
});
but no success still. Using NodeJS 4.5.0, MongoDB-Native driver 2.2.24
You should do something like console.error('Failed to connect to mongodb ',e); you are not outputting the error.
Also some events provide an additional parameter and you are outputting those either. In case of failing to connect to an mongodb server, your application should just notify you it's not the best approach to handle mongodb server start/restart from your application use daemons such as systemd or other process monitoring.
Some events are there to just notify the application that connection was lost or an reconnection is attempted, its up to you to handle what is going to be done when those events are emitted.
You can for example attempt to check mongodb status when an disconnect event is emitted an recreate connection object.
You could wrap the connect statement in a try-catch block.
I moved away from using the default connection to a explicitly defined connection.
My code is working except that none of the event handlers which track the state of my mongo connection are firing.
the events used to fire when I was using default mongoose connection. (mongoose.connect).
var mongoose = require('mongoose'),
logger = require('../logger'),
config = require('../config');
mongoose.connection.on('connecting', function(){
logger.info("trying to establish a connection to mongo");
});
mongoose.connection.on('connected', function() {
logger.info("connection established successfully");
});
mongoose.connection.on('error', function(err) {
logger.error('connection to mongo failed ' + err);
});
mongoose.connection.on('disconnected', function() {
logger.log('mongo db connection closed');
})
var gracefulExit = function() {
db.close(function(){
logger.log("mongoose connection with db " + server + 'is closing');
process.exit(0);
});
};
process.on('SIGNT', gracefulExit).on('SIGTERM', gracefulExit);
var db = mongoose.createConnection(config.get('DB_URL'));
module.exports = db;
the problem with the code is
None of the event handlers are firing.
Even the process events on SIGNT and SIGTERM are not firing.
I also tried
var db = mongoose.createConnection(config.get('DB_URL'));
db.on('connecting', function(){
logger.info("trying to establish a connection to mongo");
});
but this also doesn't fire.
i also faced with this problem,
and finally i solved it, after understood that the connect() / createConnection() execute before i declare the event handlers.
so the my open or connected events handlers will never called again.
so by declare them first and just after trying to connect - will solve your problem!
for example:
try {
mongoose.connection
.on('error', err => {
console.error(err);
})
.on('open', err => {
console.log(`DB connected`);
})
await mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true });
} catch (error) {
handleError(error);
}
This snippet blow work fine for me
const connection = mongoose.createConnection(`mongodb://${process.env.MONGO_URI}`);
connection.on('connected', () => {
console.log('connected to mongodb');
});
connection.on('disconnected', () => {
console.log('connection disconnected');
});
I just stumbled over this issue myself and found that I needed to set up the EventListeners before the actual connection to the database like so (with async/await):
export class Database {
public static connect( databaseCredentials: string ) {
return new Promise( async resolve => {
// ! The `EventListeners` is setup here.
mongoose.connection.on( "connected", () => {
logger.info( "Database has connected successfully." );
});
mongoose.connection.on( "error", (error) => {
logger.error( " Obs! There was an unexpected error connecting to the database.", error );
});
// ! The acutal connection to the database happens here.
await mongoose.connect( databaseCredentials, {
useNewUrlParser: true,
useUnifiedTopology: true,
keepAlive: true,
reconnectInterval: 500,
connectTimeoutMS: 10000,
});
resolve();
});
}
}
This should also work the same way with mongoose.createConnections.
This will yield the result (if successful):
{ message: 'Database has connected successfully.',
level: 'info',
timestamp: '2019-10-11T15:17:16.616Z' }
I just wanted to chip in and give my solution to the problem at hand and give a full example implementation of the code, as the above answers didn't explain in which order you needed to listen for the events. If you were to put the mongoose.connection.on() below the await.mongoose.connect(), this would not yield any response from the EventListeners.
Edit: Typos
try:
mongoose.connection.on('open', function() {
logger.info("database is ready now");
});
also temporary remove .close()