I'm building a nodeJS authentication API, I found a lot of resources on GitHub, I'm confused about writing and hundle promise error and I want to understand it to change some code on the cloned project.
The first function is register located on register service :
async function register(params, origin) {
// validate
if (await db.Account.findOne({ email: params.email })) {
// send already registered error in email to prevent account enumeration
return await sendAlreadyRegisteredEmail(params.email, origin);
}
// create account object
const account = new db.Account(params);
// first registered account is an admin
const isFirstAccount = (await db.Account.countDocuments({})) === 0;
account.role = isFirstAccount ? Role.Admin : Role.User;
account.verificationToken = randomTokenString();
// hash password
account.passwordHash = hash(params.password);
// save account
await account.save();
// send email
await sendVerificationEmail(account, origin);
}
when an account is already registered I want to return an error not sending an email ( line 5 )
account controller
here is the controller where I want to handle the promise returned from account service :
router.post('/register', registerSchema, register);
function register(req, res, next) {
accountService.register(req.body, req.get('origin'))
.then(() => res.json({ message: 'Registration successful, please check your email for verification instructions' }))
.catch(next);
}
I thought that .catch function trait a rejected promise isn't it ? what does .catch(next) do exactly ? and in case where an account exist already when register how to return an api error with a status code ?
You are mixing 2 ways of handling promise in Javascript in one
.catch is to handle promise rejection from .then block.
With the async-await syntax, we need to handle promise rejection with a try-catch block.
In your register function just wrap all await part in one try-catch block and it will be handled.
You could handle an "account exists" condition as an error, using throw
& catch
.
However, I'd make the register
function return a status message or other indicator to the caller so it can be used in a more flexible & reusable way.
async function register(params, origin) {
// validate
if (await db.Account.findOne({ email: params.email })) {
// send already registered error in email to prevent account enumeration
return {success: false, await sendAlreadyRegisteredEmail(params.email, origin)};
}
// create account object
const account = new db.Account(params);
// first registered account is an admin
const isFirstAccount = (await db.Account.countDocuments({})) === 0;
account.role = isFirstAccount ? Role.Admin : Role.User;
account.verificationToken = randomTokenString();
// hash password
account.passwordHash = hash(params.password);
// save account
await account.save();
// send email
return {success: true, await sendVerificationEmail(account, origin)};
}
And then you could handle the message here:
function register(req, res, next) {
accountService.register(req.body, req.get('origin'))
.then((results) => {
if (results.success) {
res.json({ message: 'Registration successful, please check your email for verification instructions' })
} else {
// send failure message
}
})
.catch(next);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.