简体   繁体   中英

how to Handle promise error in nodeJS / express

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM