UnhandledPromiseRejectionWarning: NodeJS pull request not working - node.js

I am writting following request to unfollow a user. followers are added to the database as an array.
router.put("/:id/unfollow",async (req,res) => {
if(req.body.userId !== req.params.id){
try{
const user = await User.findById(req.params.id);
const currentUser = await User.findById(req.params.id);
if (user.followers.includes(req.body.userId)){
await user.updateOne({$pull:{followers:req.body.userId}});
await currentUser.updateOne({$pull:{followers:req.params.id}});
res.status(200).json("user has been unfollowed");
}else{
res.send(403).json("you already unfollowed this user ");
}
}catch (err){
res.status(500).json(err);
console.log("err");
}
} else{
res.status(403).json("You cant unfollow yourself")
}
})
When the request is sent via postamn with the correct userId postman says "forbidden"
and the terminal shows the following error.
Whats wrong in here ?
express deprecated res.send(status): Use res.sendStatus(status) instead routes\user.js:98:21
(node:15336) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:561:11)
at ServerResponse.header (C:\Users\Banchi\Desktop\ReactTest\moodfix-api2\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (C:\Users\Banchi\Desktop\ReactTest\moodfix-api2\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (C:\Users\Banchi\Desktop\ReactTest\moodfix-api2\node_modules\express\lib\response.js:267:15)
at C:\Users\Banchi\Desktop\ReactTest\moodfix-api2\routes\user.js:102:29
at processTicksAndRejections (internal/process/task_queues.js:95:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:15336) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a prom
ise 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#c
li_unhandled_rejections_mode). (rejection id: 1)
(node:15336) [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-z
ero exit code.

inside else block of try, make following change:
try{
...
if (user.followers.includes(req.body.userId)){
...
res.status(200).json("user has been unfollowed");
} else{
// res.send(403).json("you already unfollowed this user ");
// ^^^ here is the error. It should be
res.status(403).json("you already unfollowed this user ");
}
} catch ...
Cannot set headers after they are sent to the client
This happens when you send another response behind an already sent one. And your code is doing this. First it respond with send(403) then sending json("you already unfollowed this user ") as well.

Related

I have a problem with my Discord bot (Minecraft server status bot)

This is the index.js script of the bot:
const { Client, RichEmbed } = require('discord.js')
const bot = new Client()
const util = require('minecraft-server-util')
const token = 'bot_token'
const PREFIX = 'l.'
bot.on('ready', () => {
console.log('Bot has come online.')
})
bot.on('message', message => {
let args = message.content.substring(PREFIX.length).split(' ')
switch (args[0]) {
case 'status':
util.status('IP', (PORT), (error, reponse) => {
if (error) throw error
const Embed = new RichEmbed()
.setTitle('Server Status')
.addField('Server IP', reponse.host)
.addField('Server Version', reponse.version)
.addField('Online Players', reponse.onlinePlayers)
.addField('Max Players', reponse.maxPlayers)
message.channel.send(Embed)
})
break
}
})
bot.login(token)
When I type node . in the console and I type l.status on the Discord server, it shows this error on the console:
(node:3300) UnhandledPromiseRejectionWarning: AssertionError [ERR_ASSERTION]: Expected 'options' to
be an object or undefined, got number
at C:\Users\HNRK\Desktop\LightSide\node_modules\minecraft-server-util\dist\status.js:46:25
at Generator.next (<anonymous>)
at C:\Users\HNRK\Desktop\LightSide\node_modules\minecraft-server-util\dist\status.js:8:71
at new Promise (<anonymous>)
at __awaiter (C:\Users\HNRK\Desktop\LightSide\node_modules\minecraft-server-util\dist\status.js:4:12)
at status (C:\Users\HNRK\Desktop\LightSide\node_modules\minecraft-server-util\dist\status.js:40:12)
at Object.<anonymous> (C:\Users\HNRK\Desktop\LightSide\node_modules\minecraft-server-util\dist\status.js:113:17)
at Generator.next (<anonymous>)
at C:\Users\HNRK\Desktop\LightSide\node_modules\minecraft-server-util\dist\status.js:8:71
at new Promise (<anonymous>)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:3300) 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: 2)
(node:3300) [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.
Can anybody help? I also tried a lot of different solutions, but none of them worked.
You are using an outdatet version of discord.js. Type npm i discord.js#latest into your terminal. In the latest version of discord.js, RichEmbed() has been removed and replaced by MessageEmbed().
This is an answer based on assumption since I've never used minecraft-server-util before. Also assuming that you're using the latest minecraft-server-util,
Based on the error;
Expected 'options' to be an object or undefined, got number
And, based on this commit, You should pass the 2nd argument as an object instead of PORT since it's a type of StatusOptions instead of a number.
So, instead of;
util.status('IP', (PORT), (error, reponse) => {
You should be doing;
util.status('IP', {
port: (PORT)
}, (error, reponse) => {

TypeError data.forEach is not a function

So when I send a get request in postman I am catching my 404 error in postman saying the "scream not found" ok great, but in my terminal I am getting this.
TypeError: data.forEach is not a function
at F:\dev\stfu-functions\functions\handlers\screams.js:68:18
at processTicksAndRejections (internal/process/task_queues.js:97:5)
i functions: Finished "api" in ~2s
(node:6672) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:526:11)
at ServerResponse.header (F:\dev\stfu-functions\functions\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (F:\dev\stfu-functions\functions\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (F:\dev\stfu-functions\functions\node_modules\express\lib\response.js:267:15)
at F:\dev\stfu-functions\functions\handlers\screams.js:75:29
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:6672) 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:6672) [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.
Here is my code where the error is happening Any Help is greatly apreciated.
exports.getScream =(req, res) => {
let screamData = {};
db.doc(`/screams/${req.params.screamId}`)
.get()
.then((doc) => {
if(!doc.exists){
return res.status(404).json({ error: 'Scream not found' });
}
screamData = doc.data();
screamData.screamId = doc.id;
return db
.collection('comments')
.where('screamId', '==', req.params.screamId)
.get();
})
.then((data) => {
screamData.comments = [];
data.forEach((doc) => {
screamData.comments.push(doc.data());
});
return res.json(screamData);
})
.catch((err) => {
console.error(err);
res.status(500).json({ error: err.code });
})
};

How to get rid of UnhandledPromiseRejectionWarning in Node Mongo Express Application

Greetings!
I have a Node-Express endpoint that calls addAdminController.js (Attached Below) to create a new admin.
Everything works well from functionality point of view. However, When you check if user already exists using mongoose FindOne method, it leaves a warning on the console. This however, does not stop the function from running and I'm successfully returning "Email Already in Use" as json object in Postman.
I want to know why i'm seeing this error and what am I doing wrong with Promise Handling. Your help is much appreciated.
addAdminController.js
const adminsModel = require("../../../../models/admins");
const bcrypt = require("bcryptjs");
exports.addAdminController = async (req, res, next) => {
const { name, email, password, role, image, status } = req.body;
//check if user already exists
try {
adminsModel
.findOne({ email }, (err, admin) => {
if (admin) {
res.status(400).json("Email Already in use");
return;
}
})
.exec();
} catch (error) {
return res.status(500).json("Something Went Wrong");
}
//Encrypt Password using Bcrypt
const saltRounds = 12;
const hashPass = bcrypt.hashSync(password, saltRounds);
//Create New Model with Hashed Password
const newAdmin = new adminsModel({
name: name,
email: email,
password: hashPass,
role: role,
image: image,
status: status,
});
// Save new admin user.
try {
await newAdmin.save();
res.json(newAdmin);
return;
} catch (error) {
res.status(400).json("There was an error creating admin user");
}
};
Console Warning
node:18700) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:533:11)
at ServerResponse.header (F:07_Developrs\Github\APIv2\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (F:07_Developrs\Github\APIv2\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (F:\07_Developrs\Github\APIv2\node_modules\express\lib\response.js:267:15)
at exports.addAdminController (F:\07_Developrs\Github\APIv2\routes\api\admins\addAdmin\addAdmin.controller.js:37:19)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:18700) 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:18700) [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.
First of all, you shouldn't be using callback version of findOne function because code below findOne function call will execute before the callback of findOne executes.
As code below the findOne function call depends on whether user already exists or not, await the result of adminsModel.findOne(...) and check findOne function returned a user or not.
Secondly, wrap findOne function call with try-catch block to handle rejected promise.
try {
const user = await adminsModel.findOne({ email });
if (user) {
return res.status(400).json("Email Already in use");
}
// code to run if user doesn't exists
} catch (error) {
return res.status(500).json("Something Went Wrong");
}

Mozilla throwing Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

fellow developers!
I am sending a form data PUT request to my server to upload a photo. Here's the code:
router.put("/profile-pic/new/:id", async (req, res, next) => {
try {
let user = await User.findById(req.params.id);
if (!user) return res.status(404).send("User not found...");
let form = new formidable.IncomingForm();
form.keepExtensions = true;
form.parse(req, async (err, fields, files) => {
if (err) return res.status(400).send("Image could not be uploaded.");
else if (files.profilePic) {
if (files.profilePic.size > 1000000) {
return res.status(400).send("Image can not be larger than 1MB");
}
await User.findByIdAndUpdate({ _id: user.id }, {
profilePic: {
data: fs.readFileSync(files.profilePic.path),
contentType: files.profilePic.type
}
}, { useFindAndModify: false });
}
});
res.send("Image uploaded successfully.");
} catch (ex) {
console.error(ex);
next();
}
});
So far I've been making this app using Chrome and on there all server requests work perfectly. I am uploading pictures and everything without a problem. I wanted to test out the app in Mozilla to check if I made any styling or layout errors only to find out that my Form Data was not being parsed correctly or at least not every time. When I try to upload a picture I get this error:
(node:9388) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:485:11)
at ServerResponse.header (C:\Users\Lenovo\Desktop\InstaCringe\server\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (C:\Users\Lenovo\Desktop\InstaCringe\server\node_modules\express\lib\response.js:170:12)
at C:\Users\Lenovo\Desktop\InstaCringe\server\routes\user.js:64:45
at IncomingForm.<anonymous> (C:\Users\Lenovo\Desktop\InstaCringe\server\node_modules\formidable\lib\incoming_form.js:104:9)
at IncomingForm.emit (events.js:210:5)
at IncomingForm._error (C:\Users\Lenovo\Desktop\InstaCringe\server\node_modules\formidable\lib\incoming_form.js:298:8)
at IncomingMessage.<anonymous> (C:\Users\Lenovo\Desktop\InstaCringe\server\node_modules\formidable\lib\incoming_form.js:134:14)
at IncomingMessage.emit (events.js:215:7)
at endReadableNT (_stream_readable.js:1184:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21)
(node:9388) 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:9388) [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.
I tried everything I could think of and nothing. So i just want to know what on Earth is going on here ... I have no unhandled promise rejections since I wrap every single router into a try-catch block and call an error handler if there's a rejected promise, so I have no idea what is going on. I'm also not setting any headers what so ever. And how is it working absolutely flawlessly when using Google Chrome and throwing an error in Mozilla. Also worth mentioning is that in Mozilla the picture uploads like 1 out of 10 times.
I guess what I want to know is, am I making some stupid mistake or is it just Mozilla being Mozilla?
I think, the problem is that your final res.send("Image uploaded successfully."); is not in the else so it will be executed everytime, also when an error occurs and an response is already sent. Try to move the final res.send() in an else block under our else if.
Theoretically,
form.parse is an asynchronous function. Maybe you are thinking that you are using return statement whenever sending a response to the client. But, res.send("Image uploaded successfully."); is getting executed even before completing form.parse. And then again from form.parse it tries to send a response to the client. That is when you get the error. It has nothing to do with the browser.

How to resolve the warnings which are getting because of using mongoose query inside loop/recursive function?

I was making a notification feature for my project in which I have to update some feilds in a notification collection if user had seen the notification. So I am sending an ObjectIds of those notifications which are seen inside an array in a body feild through a post request. It is glad to see that the code is running and there is an update in mongoDB database but I am getting some warnings in my console.
My post request function :-
exports.markeNotificationRead = (req,res) => {
function asyncLoop(value){
if(value< req.body.length){
Notification.updateOne({_id:req.body[value]}, {read: true}).then((doc) => {
console.log(doc);
res.setHeader("Content-Type", "application/json");
return res.json({message: "Notification marked read"});
})
.catch(err => {
console.log(err);
return res.status(500).json(err);
});
asyncLoop(value + 1);
}
}
asyncLoop(0);
}
Warnings :-
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:485:11)
at C:\Users\XYZ\PROJECT\handlers\users.js:318:17
at processTicksAndRejections (internal/process/task_queues.js:93:5) {
code: 'ERR_HTTP_HEADERS_SENT'
}
(node:25968) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:485:11)
(node:25968) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:485:11)
at ServerResponse.header (C:\Users\XYZ\PROJECT\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (C:\Users\XYZ\PROJECT\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (C:\Users\XYZ\PROJECT\node_modules\express\lib\response.js:267:15)
at C:\Users\XYZ\PROJECT\handlers\users.js:324:36
at processTicksAndRejections (internal/process/task_queues.js:93:5)
(node:25968) 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:25968) [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.
I have also used foreach loop but still I am getting same warning. So what should I do now.

Resources