Reputation: 41
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.
Upvotes: 2
Views: 1195
Reputation: 29334
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");
}
Upvotes: 1