I am trying to add user authentication to my site. The register route on my page works perfectly but I receive an Unhandled promise rejection warning when I try to send a request to the login route.
I've tried adding .catch(err => console.log(err)); and
.catch(console.log("Something's gone wrong.")); to the end of both .findOne().then() and .compare().then(), but that didn't help.
router.post("/login", (req, res) => {
const email = req.body.email;
const password = req.body.passowrd;
User.findOne({ email }).then(user => {
if (!user) {
return res.status(404).json({ email: "User not found" });
}
bcrypt.compare(password, user.passowrd).then(isMatch => {
if (isMatch) {
res.json({ msg: "Success" });
} else {
return res.status(400).json({ password: "Password incorrect" });
}
});
});
});
The code is supposed to simply send back a message that the passwords match, so I can later generate a token. I get this error:
(node:18152) UnhandledPromiseRejectionWarning: Error: Illegal arguments: undefined, undefined
at _async (/home/jok/code/node_modules/bcryptjs/dist/bcrypt.js:286:46)
at /home/jok/code/node_modules/bcryptjs/dist/bcrypt.js:307:17
at new Promise (<anonymous>)
at Object.bcrypt.compare (/home/jok/code/node_modules/bcryptjs/dist/bcrypt.js:306:20)
at User.findOne.then.user (/home/jok/code/routes/api/users.js:64:12)
at processTicksAndRejections (internal/process/next_tick.js:81:5)
(node:18152) 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:18152) [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 UnhandledPromiseRejectionWarning occurs because you're not handling the Promise rejection, meaning that you're missing a .catch handler.
bcrypt.compare(password, user.passowrd).then(isMatch => {
if (isMatch) {
res.json({ msg: "Success" });
} else {
return res.status(400).json({ password: "Password incorrect" });
}
})
.catch(err => {
res.status(500).send('Internal server error');
});
In this particular case, it seems that password & user.passowrd are undefined. The latter probable because of a typo: passowrd => password.
So it's recommended to check that the arguments sent to your route are valid.
router.post("/login", (req, res) => {
const email = req.body.email;
const password = req.body.passowrd;
if(!email || !password)
return res.status(400).send('email & password are required');
/* ... */
});
Since you're missing the .catch handler also on the .findOne Promise, it's always better to chain Promises instead of nesting them as you're doing. So here's the complete code:
router.post("/login", (req, res) => {
const email = req.body.email;
const password = req.body.passowrd;
if (!email || !password)
return res.status(400).send('email & password are required');
User.findOne({ email })
.then(user => {
if (!user) {
return res.status(404)
.json({ message: "User not found" });
}
return bcrypt.compare(password, user.passowrd);
})
.then(isMatch => {
if (typeof isMatch !== 'boolean')
return; // result from `res.status(404)...`
if (isMatch)
return res.json({ message: "Success" });
return res.status(400)
.json({ message: "Password incorrect" });
})
.catch(err => {
res.status(500).json({ message: 'Internal server error' });
});
});
I've tried adding .catch(err => console.log(err)); and
.catch(console.log("Something's gone wrong.")); to the end of both
.findOne().then() and .compare().then(), but that didn't help.
Either you didn't attach the handler correctly, or the warning was triggered in another code. But since the provided code does not have the .catch you mention, I can't confirm. Anyways, the above snippet won't trigger an UnhandledPromiseRejectionWarning
bcrypt.compare(myPlaintextPassword, hash, function(err, res) {
if (err) {
console.log(err);
}
// Use your response
});
That is not necessary to use promises in simple logic.
Related
I am using below for JWT:
let jwtoptions = {};
jwtoptions.jwtFromRequest = ExtractJWT.fromAuthHeaderAsBearerToken();
jwtoptions.secretOrKey = DB.secret;
let Strategy = new JWTStrategy(jwtoptions,(jwt_payload,done)=>{
User.findById(jwt_payload.id)
.then(User =>{
return done(null, User);
})
.catch(err =>{
return done(err,false);
})
})
passport.use(Strategy);
But its showing me below error:
(node:14224) UnhandledPromiseRejectionWarning: TypeError: done is not a function
(node:13568) 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().
Haven't used passport-jwt but from reading the docs it seems you need to use a callback instead of a promise
let Strategy = new JWTStrategy(jwtoptions,(jwt_payload,done)=>{
User.findById(jwt_payload.id, (err, user) => {
if (err) return done(err, false);
return done(null, user);
});
});
(node:13384) UnhandledPromiseRejectionWarning: TypeError: cb is not a function
I am using passport js for authentication for my website, I am able to get all routes but when I try to sign up that is post router so in the console I am seeing these err, my data saved in DB but after posting my page loading continuously.
here these err what I am getting
(node:13384) UnhandledPromiseRejectionWarning: TypeError: cb is not a function
at C:\Users\SBCS\Desktop\AppBlog\node_modules\passport-local-mongoose\index.js:247:59
at processTicksAndRejections (internal/process/task_queues.js:93:5)
(Use node --trace-warnings ... to show where the warning was created)
(node:13384) 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:13384) [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 here is my post router code
app.post("/sign-up",(req,res)=>{
const username = req.body.username
const email = req.body.email
const password = req.body.password
User.register( {username:username}, req.body.email,req.body.password ,(err,user)=>{
if(err){
console.log(err);
res.redirect("/sign-up")
}else{
passport.authenticate("local" )(req,res, function (){
res.redirect('/compose')
})
}
})
and here is my mongoose connection
mongoose.connect('mongodb://localhost:27017/blog', {useNewUrlParser: true, useUnifiedTopology: true,useFindAndModify: false}).catch(err => console.log(err))
mongoose.set('useCreateIndex',true);
thanks
when I am getting err node js referring me this modules code see here
schema.statics.register = function(user, password, cb) {
// Create an instance of this in case user isn't already an instance
if (!(user instanceof this)) {
user = new this(user);
}
const promise = Promise.resolve()
.then(() => {
if (!user.get(options.usernameField)) {
throw new errors.MissingUsernameError(options.errorMessages.MissingUsernameError);
}
})
.then(() => this.findByUsername(user.get(options.usernameField)))
.then(existingUser => {
if (existingUser) {
throw new errors.UserExistsError(options.errorMessages.UserExistsError);
}
})
.then(() => user.setPassword(password))
.then(() => user.save());
if (!cb) {
return promise;
}
promise.then(result => cb(null, result)).catch(err => cb(err));
};
this is passport-local-mongoose module code
i got answer
this cause by
User.register( {username:username}, req.body.email,req.body.password ,(err,user)=>{
if(err){
line of code and after spending more time on it,I got some solution
solution is here
User.register({username: req.body.username}, req.body.password, function(err, user){
also if you want to send user name you can send it like this
User.register({username: req.body.username,name: req.body.registerName}, req.body.password, function(err, user){
thanks .....
const Car = mongoose.model('Car', new mongoose.Schema({
name: {
type: String,
required: true,
}
}));
router.put('/:id', async (req, res) => {
const { error } = joiValidator(req.body);
if (error) return res.status(400).send(error.details[0].message)
try {
const car= await Car.findByIdAndUpdate(req.params.id, { name: req.body.name }, {new: true })
} catch (error) {
return res.status(404).send('not found.');
}
res.send(car);
})
i am successfully connected to mongoDB using mongoose, its only when i try to mock an error by giving a wrong id as an input i get the following error, even though i handled async and await with the trycatch block
(node:19392) 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:19392) [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.
This is mainly because you are using try an catch after an if. In javascript the way of reading code is asynchronous so, if and try are executed at the same time. Also, you donĀ“t need to use an async function here, as you are only calling one promise.
Here I let you a simpler code without async.
router.put("/:id", (req, res) => {
const { error } = joiValidator(req.body);
if (error) {
return res.status(400).send(error.details[0].message);
} else {
Car.findByIdAndUpdate(req.params.id,{ name: req.body.name },{ new: true },(err, car) => {
if (err) return res.status(404).send({ message: 'Not found', err });
return res.status(200).send(car);
}
);
}
});
Hi I'm new at javascript programming.
I have a node express project, I'm trying to create a login method inside my AuthenticationController class.
My login method is like this right now:
const User = require('../models/User')
class AuthenticationController {
async login(req, res) {
const { email, password } = req.body
console.log('step 1')
var hashPassword = await userPassword(email)
console.log(hashPassword)
console.log('step 2')
return res.status(200).json({ 'msg': 'Log in OK!' })
}
userPassword(email) {
User.findOne({ email: email }).exec(function(err, user) {
if (err) return err
else return user.password
})
}
}
But I got an error saying that userPassword is undefined, I couldn't figure out why. So my doubts are: why this is happening, and how to do it correctly ?
I also checked out this questions, but they didn't helped me:
How to call an async function
Async function inseide a class
The error message at my console:
(node:28968) UnhandledPromiseRejectionWarning: ReferenceError: userPassword is not defined
...
(node:28968) 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:28968) [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.
login doesn't refer to userPassword method but to the function of the same name which doesn't exist.
Promises are supposed to be be chained and they aren't. userPassword is expected to return a promise but it uses obsolete Mongoose callback API.
That UnhandledPromiseRejectionWarning is shown means that errors weren't correctly handled in login while they should. As explained in this answer, Express don't support promises so errors should be handled by a developer.
It should be:
async login(req, res) {
try {
const { email, password } = req.body
var hashPassword = await this.userPassword(email)
return res.status(200).json({ 'msg': 'Log in OK!' })
} catch (err) {
// handle error
}
}
async userPassword(email) {
const { password } = await User.findOne({ email: email });
return password;
}
this error is coming because you are not handling error for the promise. Always use async/await inside try/catch block.
try{
async login(req, res) {
const { email, password } = req.body
console.log('step 1')
var hashPassword = await userPassword(email)
console.log(hashPassword)
console.log('step 2')
return res.status(200).json({ 'msg': 'Log in OK!' })
}
}catch(e){
console.log(e)
}
I'm trying to learn node.js
I've got a working function and trying to handle an exeption like this:
Client.Session.create(device, storage, username, password)
.then(function(session) {
session.getAccount()
.then(function(account) {
console.log(account.params)
res.statusCode = 200
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify(account.params));
return session
})
}).catch(Exceptions.AuthenticationError, function(err) {
console.log(err)
})
but it isn't working I'm still getting this in case of invalid login:
Unhandled rejection AuthenticationError: The username you entered doesn't appear to belong to an account. Please check your username and try again.
Try
Client.Session.create(device, storage, username, password)
.then(function(session) {
return session.getAccount() <-- NOTICE THE RETURN STATEMENT!!
.then(function(account) {
console.log(account.params)
res.statusCode = 200
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify(account.params));
return session
})
}).catch(Exceptions.AuthenticationError, function(err) {
console.log(err)
})
Without the return, the .then handler of the promise returned by Client.Session.Create(...) will return a resolved promise (this is its default behaviour).
Promise rejections aren't any kind of exceiptions, so they aren't automatically rethrown as it would be if you were added, for example, something like this:
session.getAccount(...).then(...).catch(function(){throw "FooBar"});