Node UnhandledPromiseRejectionWarning when saving to MongoDb - javascript

New to node- I'm trying to save some of my tweets from Twitter API into mongo using Twit package.
I've connected to mongodb on port 27017 using mongoose, and this piece of code I've written seems to save the tweets to my db, however I seem to be getting this warning back everytime I save a document:
(node:9991) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 8)
Here is my code:
const Tweet = require('./app/models/tweet.model.js');
const dbConfig = require('./config/database.config.js');
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect(dbConfig.url, {
useNewUrlParser: true
}).then(() => {
console.log("Successfully connected to the database");
}).catch(err => {
console.log('Could not connect to the database. Exiting now...', err);
process.exit();
});
var Twit = require("twit");
var config = require("./config/twitter.config");
var T = new Twit(config);
var params = {
screen_name: "decade3uk",
count: 2
};
T.get("statuses/user_timeline", params, gotData);
function gotData(err, data, response) {
var tweets = data;
for(var i=0;i<tweets.length;i++){
const tweet = new Tweet({
created_at:tweets[i].created_at,
id_str:tweets[i].id_str,
text:tweets[i].text
});
tweet.save()
.then(entry => {
response.send(entry);
}).catch(err => {
response.status(500).send({
message: err.message || "Some error occurred while creating the Tweet."
});
});
}
}
What is best practice to get rid of this error?

Why don't you try to find where is that exception coming from and what exactly it is. You can find that by adding the following code to your server file, just to make sure you get what's causing the exception.
process.on('unhandledRejection', (reason, promise) => {
console.log("Reason: ",reason,"promise: ",promise);
})

Related

field in mongoose model is required : true but it is being created in postman

i am trying to give only name in the body and want error in the postman ...but for the status response in postman is 201 created but it is throwing error in console as
UnhandledPromiseRejectionWarning: ValidationError: User validation failed: password: Path password is required., email: Path email is required.
at model.Document.invalidate (C:\projects\MERN\backend\node_modules\mongoose\lib\document.js:2564:32)
at C:\projects\MERN\backend\node_modules\mongoose\lib\document.js:2386:17
at C:\projects\MERN\backend\node_modules\mongoose\lib\schematype.js:1181:9
at processTicksAndRejections (internal/process/task_queues.js:79:11)
(node:6524) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:6524) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
why there is no error in postman???????????
const mongoose = require('mongoose')
const userSchema = new mongoose.Schema({
name:{
type : String,
required : true
},
email:{
type : String,
required : true,
unique:true,
},
password:{
type : String,
required : true,
minlength: 7
},
date:{
type :Date,
default: Date.now
}
})
const User = mongoose.model('User',userSchema)
module.exports = User
router.post("/", async (req, res) => {
try {
const user = await new User(req.body);
user.save();
res.status(201).send({user});
} catch (e) {
res.status(500).send(e);
}
});
consider that your node application throws some error right and crashes as you describe well above. Because your node app is interfacing with the internet you need to devise a way to interpret the error from you app into to an error that is known by the internet also, that way postman will be able to tell that an error has occured...So how do we achieve this, the answer is error handling...
We will use your User model as you have described, and consider the code below it...
router.post("/", async (req, res) => {
try {
const user = await new User(req.body);
// One important thing to note is that the return of this function call below is
// a Promise object which means that it executes asynchrounously and from the error
// log you have above, it is the reason your app is crashing...
user.save();
res.status(201).send({user});
} catch (e) {
res.status(500).send(e);
}
});
So then lets fix it...
router.post("/", async (req, res) => {
const user = await new User(req.body);
return user.save()
// the then call simply accepts a callback that is executed after the async is complete
.then((result) => res.status(201).send({user}))
// this catch will be called in case the call encounters an error during execution
.catch((error) => res.status(500).send(error));
});
Note now we handle the error in the catch by responding to the HTTP request as you have with a 500 code...and also sending the error along with the response

Giphy not working on Discord bot (javascript)

I was following this tutorial on how to make a discord bot, everything was working fine until 33:32 where he added the giphy stuff i had already installed giphy sdk/api, created an application, but after he made the search statement he said you can console log it so i did it, and there were some gif results coming out, which returned undefined on my console(i dunno why), then he added some math stuff, which i also did, then at the point where he added the messaging part where he also added this code files:[responseFinal.images.fixed_height.url] which then returned this on my console
(node:3136) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'images' of undefined
at D:\Discord bots\Oboto v2.0\index.js:24:61
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:3136) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:3136) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
and this confused the flip outta me, then i picked an alt approach, instead of doing giphy.search i did
giphy.random with the same arguments, removed the math stuff and console.log(response)the response and guess what it actually gave me a single gif!(in the console of course) then i implemented to my files:[]statement aaaaand it returned the same thing (cannot read property 'images' of undefined) im also kinda new to discord.js and javascript, also here is my entire code,
const Discord = require('discord.js');
const { prefix, token, giphyToken } = require('./config.json');
const client = new Discord.Client();
var GphApiClient = require('giphy-js-sdk-core')
giphy = GphApiClient(giphyToken)
client.once('ready', () => {
console.log('Ready!');
});
client.on('message', message => {
if (message.member.hasPermission(["KICK_MEMBERS", "BAN_MEMBERS"])){
if (message.content.startsWith(`${prefix}kick`)) {
let member = message.mentions.members.first();
member.kick().then((member) =>{
giphy.random('gifs', {'q':'fail'})
.then((response) => {
console.log(response);
message.channel.send(":wave:",{files:[response.images.fixed_height.url]});
})
})
}
}
})
client.login(token);
cannot read property 'images' of undefined, this means you are trying to access a null object. Same as null pointer exception in java. It means your response is null.
And you are also getting UnhandledPromiseRejectionWarning which means your promise is throwing error which you are not catching anywhere. You can catch your error like this
member.kick().then((member) =>{
giphy.random('gifs', {'q':'fail'})
.then((response) => {
console.log(response);
message.channel.send(":wave:",{files:[response.images.fixed_height.url]});
}).catch(e => { console.error(e}) }
}).catch(e => { console.error(e) }
Now you can see what error you are getting. You can also use try catch approach with async await.
THIS CODE IS FIXED BY ME :D
Discord Bot - Kick member with Giphy
IM NOT A PROFESSIONAL AT ALL.
You can also add this giphy to new member notice.
const Discord = require('discord.js');
const { prefix, token, giphyToken } = require('./config.json');
const bot = new Discord.Client();
var GphApiClient = require('giphy-js-sdk-core');
bot.giphy = GphApiClient(giphyToken);
bot.on('message', (message) => {
if (message.member.hasPermission(['KICK_MEMBER', 'BAN_MEMBERS'])) {
//console.log(message.content);
if (message.content.startsWith(`${prefix}kick`)) {
//message.channel.send("kick")
let member = message.mentions.members.first();
member.kick().then((member) => {
bot.giphy.search('gifs', { q: 'fail' }).then((response) => {
var totalResponses = response.data.length;
var responseIndex = Math.floor(Math.random() * 10 + 1) % totalResponses;
var responseFinal = response.data[responseIndex];
message.channel.send(':wave: ' + member.displayName + ' has been kicked!',{
files: [responseFinal.images.fixed_height.url]
}
)
})
})
}
}
});
bot.login(token);

NodeJS - How to deal with UnhandledPromiseRejectionWarning?

I am fairly new to Node JS and so I am struggling a bit.
I am trying to read files for google drive using their API, from my Node Js code.
I am having the following code
router.get('/', function (req, res, next) {
var pageToken = null;
// Using the NPM module 'async'
async.doWhilst(function (callback) {
drive.files.list({
q: "mimeType='image/jpeg'",
fields: 'nextPageToken, files(id, name)',
spaces: 'drive',
pageToken: pageToken
}, function (err, res) {
if (err) {
// Handle error
console.error(err);
callback(err)
} else {
res.files.forEach(function (file) {
console.log('Found file: ', file.name, file.id);
});
pageToken = res.nextPageToken;
callback();
}
});
}, function () {
return !!pageToken;
}, function (err) {
if (err) {
// Handle error
console.error(err);
} else {
// All pages fetched
}
})
res.render('index', { title: 'Express' });
});
The above code is giving me the following error when i send the get request
(node:13884) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'forEach' of undefined
at E:\nodejs\newcelebapi\routes\index.js:49:17
at E:\nodejs\newcelebapi\node_modules\googleapis-common\build\src\apirequest.js:43:53
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:13884) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:13884) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
The issue is in the following line
res.files.forEach(function (file) {
I've tried everything I could and gave up understanding the problem.
Could you please help me with this?
Thanks!
Per this example in the doc, you want to be using:
res.data.files.forEach(...)
not:
res.files.forEach(...)
And, it looks like as soon as you get by that problem, you will have another problem because you are calling res.render() in the wrong place. And, when you fix that, you will have an issue with redefining res in your Google callback which will hide the higher level res that you need for res.render().
I would strongly recommend that you not use the async library here. It doesn't seem like it's needed here and it just complicates things. And, if you did need help doing coordination of asynchronous operations, promises is the modern way to do so.
You don't show what you're trying to do with the resulting files (other than logging them), but here's a simple implementation that does that:
router.get('/', function (req, res, next) {
var pageToken = null;
drive.files.list({
q: "mimeType='image/jpeg'",
fields: 'nextPageToken, files(id, name)',
spaces: 'drive',
pageToken: pageToken
}).then(response => {
let files = response.data.files;
files.forEach(file => console.log('Found file: ', file.name, file.id))
res.render('index', { title: 'Express' });
}).catch(err => {
console.log(err);
res.sendStatus(500);
});
});
Note, that I named the parameter from drive.files.list() to be named response instead of res so I can access both res from the router.get() callback and response from the drive.files.list() callback. You gave them both the same name res which means you can't access the router.get() parameter of the same name.

node/pg/PSQL: Create Tables using Promises

I am writing a simple Node/Express/React/Postgres application and I'm using the pg package to interface with my Postgres Server.
I require three tables, table1, table2, and table3. table2 has a foreign key in table1 and table3 has a foreign key in table 2, so the order that I need to create the tables in is: table1 then table2 then table3.
I am attempting to use promises to enforce this order in my asynchronous table creation calls. I've generally followed Brian Carlson's suggested Project Structure, but clearly I'm doing something wrong.
Here are the simplified, relevant files from my project:
db.js:
const { Pool } = require('pg');
// Create pool connection to database
const pool = new Pool({
user: XXXX,
host: XXXX,
database: XXXX,
password: XXXX,
port: XXXX
});
// Pool emitters
pool.on('connect', () => {
console.log('Connected a client to the database');
});
pool.on('remove', () => {
console.log('Disconnected a client from the database');
});
pool.on('error', (err, client) => {
console.error('Unexpected error on idle client', err);
process.exit(-1);
});
// This structure taken from Brian Carlson's pg API Documentation
// https://node-postgres.com/guides/project-structure
module.exports = {
query: (text, params) => {
console.log('Making a query!');
return pool.query(text, params);
}
};
table_scripts.js:
const db = require('../db');
const Database_Scripts = {
create_table_1: () => {
const create_table_1_query = {
text: `CREATE TABLE IF NOT EXISTS
public.table_1
(
id smallserial,
name text NOT NULL,
PRIMARY KEY (id)
);`
};
return db.query(create_table_1_query);
},
create_table_2: () => {
const create_table_2_query = {
text: `CREATE TABLE IF NOT EXISTS
public.table_2
(
id smallserial,
table_1_id integer NOT NULL REFERENCES public.table_1(id),
name text NOT NULL,
PRIMARY KEY (id)
);`
};
return db.query(create_table_2_query);
},
create_projects_table: () => {
const create_table_3_query = {
text: `
CREATE TABLE IF NOT EXISTS
public.table_3
(
id smallserial,
table_3_id integer NOT NULL REFERENCES public.table_2(id),
name text NOT NULL,
PRIMARY KEY (id)
);`
};
return db.query(create_table_3_query);
}
};
module.exports = Database_Scripts;
create_tables.js:
const Table_Scripts = require('./table_scripts');
Table_Scripts.create_table_1()
.then(Table_Scripts.create_table_2())
.then(Table_Scripts.create_table_3())
.catch(error => console.log(error.stack));
package.json:
{
"name": "app",
"version": "0.0.0",
"scripts": {
"start": "nodemon ./bin/www",
"create_tables": "node ./database/scripts/create_tables.js"
}
}
When I run my create_tables script (npm run-script create_tables), I get the following (sanitized) errors:
Connected a client to the database
Connected a client to the database
Connected a client to the database
Disconnected a client from the database
(node:13444) UnhandledPromiseRejectionWarning: error: relation "public.table_1" does not exist
(node:13444) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a
catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:13444) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Disconnected a client from the database
(node:13444) UnhandledPromiseRejectionWarning: error: relation "public.table_2" does not exist
(node:13444) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a
catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
Disconnected a client from the database
I've been able to get this script to work converting the functions to async functions, however, I'd really like to understand what I'm doing wrong here.
Your problem seems to be that you're concurrently creating the tables despite explicitly needing to do the opposite.
According to the documentation, pool.query() returns a promise if not provided a callback function as a third argument. You need to wait for each of your db.query() promises to be resolved. Thus it'll wait for the first table to be created, then create the second one and finally the third one.
I would recommend using the async/await syntax
async function createTables () {
try {
const create_table_1_query = {
text: `yourQuery1`
};
// awaits for the first table to be created
await db.query(create_table_1_query);
const create_table_2_query = {
text: `yourQuery2`
};
// awaits for the second table to be created
await db.query(create_table_2_query);
const create_table_3_query = {
text: `yourQuery3`
};
// awaits for the third table to be created
await db.query(create_table_3_query);
} catch (e) {
console.error(e.stack);
}
}
module.exports.createTables = createTables;
You can then call await createTables();

Trouble understanding my errors when trying to create my MongoDB database connection on my javascript server using node.js

I am currently taking a web course and am almost always struggling to debug my code and the errors Node returns don't seem to help.
I am creating a web server and trying to create username and password authentication with MongoDB and JavaScript. When I call my initialize function I get a wack load of errors. I know it is coming from my Database initialization function because when I take it out of my initial server initialization I get no errors. For the most part this code comes from my specific assignment design document so I am not looking for anything that's more efficient etc.
Working Code without MongoDB function:
data.initialize().then(function(){
app.listen(HTTP_PORT, function(){
console.log("app listening on: " + HTTP_PORT)
});
}).catch(function(err){
console.log("unable to start server: " + err);
});
Code that isn't working:
data.initialize().then(dataServiceAuth.initialize).then(function(){
app.listen(HTTP_PORT, function(){
console.log("app listening on: " + HTTP_PORT)
});
}).catch(function(err){
console.log("unable to start server: " + err);
});
DataServiceAuth.initialize:
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var userSchema = new Schema({
"userName": {
unique: true,
type: String
},
"password": String,
"email": String,
"loginHistory": [{ "dateTime": Date, "userAgent": String }]
});
let User; //to be defined on new connection
module.exports.initialize = function () {
return new Promise(function (resolve, reject) {
let db = mongoose.createConnection("mongodb://<Removed username>:<removed password>#ds017193.mlab.com:17193/web322_a6");
db.on('error', (err) => {
reject(err); // reject the promise with the provided error
});
db.once('open', () => {
User = db.model("users", userSchema);
resolve();
});
});
};
and last but not least all the errors
(node:6968) UnhandledPromiseRejectionWarning: Error: Username contains an illegal unescaped character
at parseConnectionString (C:\Users\Jasper\Desktop\School\web322\WEB322-A5-solution\node_modules\mongodb\lib\url_parser.js:280:11)
at parseHandler (C:\Users\Jasper\Desktop\School\web322\WEB322-A5-solution\node_modules\mongodb\lib\url_parser.js:119:14)
at module.exports (C:\Users\Jasper\Desktop\School\web322\WEB322-A5-solution\node_modules\mongodb\lib\url_parser.js:25:12)
at connect (C:\Users\Jasper\Desktop\School\web322\WEB322-A5-solution\node_modules\mongodb\lib\mongo_client.js:874:3)
at connectOp (C:\Users\Jasper\Desktop\School\web322\WEB322-A5-solution\node_modules\mongodb\lib\mongo_client.js:269:3)
at executeOperation (C:\Users\Jasper\Desktop\School\web322\WEB322-A5-solution\node_modules\mongodb\lib\utils.js:419:24) at MongoClient.connect (C:\Users\Jasper\Desktop\School\web322\WEB322-A5-solution\node_modules\mongodb\lib\mongo_client.js:260:10)
at Promise (C:\Users\Jasper\Desktop\School\web322\WEB322-A5-solution\node_modules\mongoose\lib\connection.js:427:12)
at new Promise (<anonymous>)
at NativeConnection.Connection.openUri (C:\Users\Jasper\Desktop\School\web322\WEB322-A5-solution\node_modules\mongoose\lib\connection.js:424:19)
at Mongoose.createConnection (C:\Users\Jasper\Desktop\School\web322\WEB322-A5-solution\node_modules\mongoose\lib\index.js:167:17)
at C:\Users\Jasper\Desktop\School\web322\WEB322-A5-solution\data-service-auth.js:18:27
at new Promise (<anonymous>)
at module.exports.initialize (C:\Users\Jasper\Desktop\School\web322\WEB322-A5-solution\data-service-auth.js:17:12)
at <anonymous>
(node:6968) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside
of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:6968) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Categories