catch error of my exported async/await function [duplicate] - javascript

This question already has answers here:
Why is it possible to try-catch an async-await call?
(2 answers)
Closed 2 years ago.
I have module that check username is unique or no!
my module is:
// Check for uniqueness username
const UsernameUniqueness = async (_username) => {
const username = await Users.findOne({
username: _username
});
if (username) {
return false;
}
return true;
}
exports.UsernameUniqueness = UsernameUniqueness;
and I have a route that I post username to it.
const FormUniqueness = require('../modules/form-uniqueness');
router.post('/register', redirectDashboard, async (req, res, next) => {
const ( username } = req.body;
try {
console.log(FormUniqueness.UsernameUniqueness(userName));
} catch (error) {
// Internal server error 500
console.log('here');
error.status = 500;
next(error);
}
}
I want when I have an error in "const username = await Users.findOne({
username: _username
}); my error throw in try/catch of my route!"
How can I do this?

Catch the error also in your function
const UsernameUniqueness = async (_username) => {
try {
const username = await Users.findOne({
username: _username
});
if (username) {
return false;
}
return true;
} catch(error) {
throw error;
}
}
exports.UsernameUniqueness = UsernameUniqueness;

Related

router.get function in node.js doesn't await funcition [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
How to properly return a result from mysql with Node?
(6 answers)
Closed 25 days ago.
This post was edited and submitted for review 25 days ago.
I' m building a email verification for my website in node.js and for it to work it changes a value in a mysql database, it has to return 1 or 0 if it works or doesn't work but the code doesn' t wait for the return and inmidiatly goes further even though I use async and await.
this is the code I used in the pages.js:
router.get("/verify-email", async (req,res) => {
var tokens = req.query.token
console.log(tokens)
const verified = await emailverification(tokens)
console.log("hello",verified)
if (verified == 1) {
res.sendFile('verifySuccess.html',{root: "./public"});
} else {
res.sendFile('verifyFail.html',{root: "./public"});
}
})
and this is the funciton it has to wait for:
const emailverification = async(token,req,res,next) => {
var tokens = token
console.log("hello",tokens)
db.query('SELECT * FROM users WHERE token = ?',[tokens], async(err, result) =>{
console.log("1")
if (err) throw err;
console.log(result)
if(result[0].verify == "0"){
console.log("2")
console.log(result[0].email)
if (result.length > 0) {
console.log("2.5")
var email = result[0].email
console.log(email)
console.log("2.75")
db.query('UPDATE users SET verify = 1 WHERE email = ?', email, async(err, result) => {
console.log(result[0])
console.log("3")
if(err) throw err
return 1
})
} else {
console.log("5")
return 0;
}
}else{
console.log("6")
return 0;
}
})
}
module.exports = emailverification;
I searched on goolge and here on stackoverflow and found a lot of stuff about this but it doesn't work in my code.
this is the source code: the source code
the follwing 2 questions:
how-do-i-return-the-response-from-an-asynchronous-call and how-to-properly-return-a-result-from-mysql-with-node don't help because those questions ar abour something else and not about the problem I have. because by my problem the code doesn' t return the stuff before contini=uing even though I use the async/awaint things like they do by these 2 questions
please don't mind all the logs I use them to see what runs and what doesn't,
you have to return like this.
const emailverification = async (req, res) => {
var tokens = req.tokens;
return db.query(
"SELECT * FROM users WHERE token = ?",
[tokens],
async (err, result) => {
if (err) throw err;
if (result[0].verify == 0) {
console.log(result[0].email);
if (result.length > 0) {
var email = result[0].email;
console.log(email);
console.log("2.75");
db.query(
"UPDATE users SET verify = 1 WHERE email = ?",
email,
async (err, result) => {
console.log(result[0]);
console.log("3");
if (err) throw err;
}
);
return res.status(200).send({ message: "true" });
} else {
var message = { status: "error", error: "email already verified" };
console.log("5");
return res.status(400).send({ message: "false" });
}
} else {
console.log(result);
console.log("6");
message = { status: "error", error: "email already verified" };
return res.status(400).send({ message: "false" });
}
}
);
};
module.exports = emailverification;

Why do I occasionally get a 502 bad gateway error in my Express REST API?

I am currently testing out REST API stuff using Express... It works and stuff, but when I keep calling requests and tweaking variables between each request, every 3 or 4 times it returns a 502 bad gateway. I am unsure why. I'll share my code although note that its just WIP code im using to test stuff out.
Here is the code.
const express = require('express');
const bcrypt = require('bcrypt');
const router = express.Router();
// Models
const User = require('../models/User');
// User Class
class UserEntity {
// Initialize user
constructor(username, password=false) {
this.username = username;
this.password = password;
}
// Get Display Name
async getDisplayName() {
try {
const displayCheck = await User.findOne({username: this.username})
if (!displayCheck) {
return false;
}
return displayCheck.displayName;
} catch (err) {
console.log("Error while getting display name: " + err);
return false;
}
}
async login() {
// 0 = Success
// 1 = User not found
// 2 = Incorrect password
// 3 = Error or class missing password, check console
if (this.password != false) {
// Find user
try {
const userCheck = await User.findOne({ username: this.username });
if (!userCheck) {
return 1;
}
} catch (err) {
console.log("Error while checking if username exists: " + err);
return 3;
}
// Check password
try {
const userCheck = await User.findOne({username: this.username})
if (!userCheck) {
return 2;
} else {
const validPass = await bcrypt.compare(this.password, userCheck.password);
if (!validPass) {
return 2;
}
// logged in!
return 0;
}
} catch (err) {
console.log("Error while checking password: " + err);
return 3;
}
} else {
console.log("Class missing password");
return 3;
}
}
}
router.get("/test", async (req, res) => {
const user = new UserEntity("nero", "iamcool4");
const login = await user.login();
if (login == 0) {
res.send("Logged in!");
} else if (login == 1) {
res.send("User not found");
} else if (login == 2) {
res.send("Incorrect password");
} else if (login == 3) {
res.send("Error");
}
})

Post Method value is undefined

The return of email2 is undefined. The method userRepository.getAllConfirmedEmails(...) delivers the right value, but in the post methode the return is undefinded.
app.post('/login', async (req, res) => {
const { email } = req.body;
// get safetyAttribues
const safetyAttributes = await safetyAttributesClass.getSafetyAttributes(email);
// if both are true, try to send login challenge
if (safetyAttributes.isAccepted && safetyAttributes.isConfirmed) {
if (safetyAttributes.isAdmin) {
const email2;
const token = await safetyAttributesClass.generateAdminToken(email).then(async (token) => {
email2 = await userRepository.getAllConfirmedEmails(email, token).then(async (email2) => {
console.log("HIER STEHT DIE ZWEITE EMAIL-->" , email2);
})
});
}
const user = userRepository.findByEmail(email);
console.log('HIER ISTHEH <USJR', user);
if (!user) {
return res.sendStatus(400);
}
const assertionChallenge = generateLoginChallenge(user.key);
userRepository.updateUserChallenge(user, assertionChallenge.challenge);
res.send(assertionChallenge);
}
// if not, send attributes to frontend to handle client-side
else {
res.send({ isAcceptet: safetyAttributes.isAccepted, isConfiremd: safetyAttributes.isConfirmed })
}
});
You're oddly mixing async/await with #then, probably sticking with async/await will help:
const token = await safetyAttributesClass.generateAdminToken(email);
const email2 = await userRepository.getAllConfirmedEmails(email, token);
console.log("HIER STEHT DIE ZWEITE EMAIL-->", email2);
You should return email2 in your getAllConfirmedEmails callback. Like so
app.post('/login', async (req, res) => {
const { email } = req.body;
// get safetyAttribues
const safetyAttributes = await safetyAttributesClass.getSafetyAttributes(email);
// if both are true, try to send login challenge
if (safetyAttributes.isAccepted && safetyAttributes.isConfirmed) {
if (safetyAttributes.isAdmin) {
const email2;
const token = await safetyAttributesClass.generateAdminToken(email).then(async (token) => {
email2 = await userRepository.getAllConfirmedEmails(email, token)
});
}
const user = userRepository.findByEmail(email);
console.log('HIER ISTHEH <USJR', user);
if (!user) {
return res.sendStatus(400);
}
const assertionChallenge = generateLoginChallenge(user.key);
userRepository.updateUserChallenge(user, assertionChallenge.challenge);
res.send(assertionChallenge);
}
// if not, send attributes to frontend to handle client-side
else {
res.send({ isAcceptet: safetyAttributes.isAccepted, isConfiremd: safetyAttributes.isConfirmed })
}
})
;

Express dosn't get return of other function querying Mongodb [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I'm working in a simple API Key authentication, I just want to verify the given key against the user provied key.
I have a seperate file with the function querying the database, and returning true/false and the user object.
But in my route.js file, the return object is undefined even tough in my auth.js file it isn't.
I tried making the the function in router.get an async function using express-promise-router and making the function an await return var user = await auth.verify(req.params.uid, req.get("token")) but I don't realy know how async works.
router.js
[...]
router.get('/list/:uid', function(req, res) {
var user = auth.verify(req.params.uid, req.get("token"))
console.log("User: " + user) // <-- Undefined
if (user.status) {
res.send("Success")
} else {
res.status(403)
res.json({status: 403, error: "Unkown User / Token"})
}
})
[...]
auth.js
var db = require('./db')
var ObjectId = require('mongodb').ObjectId;
module.exports = {
verify: (uid, key) => {
try {
var collection = db.get().collection('users')
const obj_id = new ObjectId(uid)
const query = { _id: obj_id }
collection.find(query).limit(1).toArray(function(err, user) {
var status = 0;
var usr = {};
if (err) {throw err}else{status=1}
if (user.length <= 0) {throw "NotExistingExc"; status = 0}else{
usr = user[0];
if (key != usr.api) status = 0
}
var returnObj = {
status: status,
user: usr
} /* --> Is {
status: 1,
user: {
_id: d47a2b30b3d2770606942bf0,
name: 'Sh4dow',
groups: [ 0 ],
api: 'YWFiMDI1MGE4NjAyZTg0MWE3N2U0M2I1NzEzZGE1YjE='
}
}
*/
return returnObj;
})
} catch (e) {
console.error(e)
return {
status: 0,
user: {},
error: e
}
}
}
}
db.js (Idk if needed)
var MongoClient = require('mongodb').MongoClient
var state = {
db: null,
}
exports.connect = function(url, done) {
if (state.db) return done()
MongoClient.connect(url, { useNewUrlParser: true }, function(err, db) {
if (err) return done(err)
state.db = db
done()
})
}
exports.get = function() {
return state.db.db("database")
}
exports.close = function(done) {
if (state.db) {
state.db.close(function(err, result) {
state.db = null
state.mode = null
done(err)
})
}
}
I want to have the returnObjin auth.js in the router.get of my route.js file.
Make auth.verify return a Promise which we can then await for it inside router, You can just make the callback async no need for express-promise-router
router.get('/list/:uid', async function(req, res) {
try {
var user = await auth.verify(req.params.uid, req.get("token"))
console.log("User: " + user)
if (user.status) {
res.send("Success")
} else {
res.status(403).json({status: 403, error: "Unkown User / Token"})
}
} catch (e) {
console.error(e)
res.status(/* */).json(/* */)
}
})
auth
module.exports = {
verify: (uid, key) => new Promise((resolve, reject) => {
var collection = db.get().collection('users')
const obj_id = new ObjectId(uid)
const query = { _id: obj_id }
collection.find(query).limit(1).toArray(function(err, user) {
var status = 0;
var usr = {};
if (err) {
reject(err)
return
} else {
status = 1
}
if (user.length <= 0) {
reject(new Error("NotExistingExc"))
return
} else {
usr = user[0]
if (key != usr.api) status = 0
}
var returnObj = {
status: status,
user: usr
}
resolve(returnObj);
})
}
}
In short, the reason you get undefined is because the code in auth.js is asyncronous. But you're really close. The toArray method in MongoDB returns a promise, so you need to make sure you return that promise and then use it in the router correctly.
In auth.js, make sure verify returns a promise - just add return!
return collection.find(query).limit(1).toArray(...)
And then, change your usage of the verify to the async/await you originally tried:
router.get('/list/:uid', async function(req, res) {
var user = await auth.verify(req.params.uid, req.get("token"))
// More code here...
})

Updating `let` variable in mongoose schema.save [duplicate]

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 4 years ago.
I have some code like this:
let addUser = (req, res) => {
let user;
let message = "";
let status = 200;
bcrypt.hash(password, salt_rounds, (err, hash) => {
user = new user({
...
password: hash,
});
user.save(err => {
if(err) {
message = "No success";
status = 400;
} else {
message = "success";
}
});
res.status(status).json({
message: message,
});
});
};
However, the message variable is undefined when the response is sent. I've been searching for a while now and, unfortunately, haven't been able to find a solution similar to this problem.
Ultimately, what I would like is to be able to update the message, status, etc. variables within the bcrypt/.save closures. I have tried using callbacks and resolving promises which I'm assuming didn't work due to naivety. Regardless, any solution would be appreciated!
Note: I would not like to use any other libraries to solve this problem (which I really doubt is required in the first place)
Thanks in advance!
Change user.save into something that returns a Promise, and then call .then on that Promise:
let addUser = (req, res) => {
let user;
let status = 200;
bcrypt.hash(password, salt_rounds, (err, hash) => {
user = new user({
password: hash,
});
const savePromise = new Promise((resolve, reject) => {
user.save(err => {
if (err) {
status = 400;
reject("No success");
} else {
resolve("success");
}
});
});
savePromise.then(message =>
res.status(status).json({ message })
).catch(message =>
res.status(status).json({ message })
);
});
};
Try this, put message key in double quotes
let addUser = (req, res) => {
let user;
let message = "";
let status = 200;
bcrypt.hash(password, salt_rounds, (err, hash) => {
user = new user({
...
password: hash,
});
user.save(err => {
if(err) {
message = "No success";
status = 400;
} else {
message = "success";
}
});
res.status(status).json({
"message": message,
});
});
};

Categories