Ad

Getting Error On Await, That Await Is Valid Only On Async Function When Using Async Function

I am using async function to confirm if user exists in DB with same username or email.

Thing is that I have async functions in separate files. I am importing files into route for certain endpoint.

When I am sending request to register an user after removing

await

From User.CreateNewUser and User.ValidateUserExists it goes through, but when I send same request again the same user is added to the database without validating if user exists in the DB.

Here is my route

const express = require("express");
const router = express.Router();
const asyncHandler = require('../helpers/asyncHandler');
const validate = require('validate.js');
const User = require('../controllers/user-exists-check');


//Route for creating user

router.post('/', asyncHandler((req,res) => {
    const constraints = {
        username: {
            presence: true,
            length:{minimum:4,maximum:10}
        },
        password: {
            presence: true,
            length:{minimum:6, maximum:20} 
        },
        email: {
            presence: true,
            email:true
        }}
    const username = req.body.username;
    const email = req.body.email;
    const password = req.body.password;
    const permission_id = req.body.permission_id;

    const validation = validate({username, email, password}, constraints);
    if(validation) res.status(400).json({error: validation});

    const existingUser = await User.ValidateUserExists({username, email});
    if(existingUser) {
        if(username === existingUser.username) return res.status(400).json({error:`Username ${username} is already taken`});
        if(email === existingUser.email) return res.status(400).json({error:`Email is already taken`});
    }

    const newUser = await User.CreateNewUser({username, email, password, permission_id});
    return res.status(200).json({user: newUser})

}));


module.exports = router;

this is user exists check

const {UserNameExists, EmailExists, CreateUser} = require('./user-db-check');

async function ValidateUserExists(username, email) {
    if(!username || !email ) throw new Error('Not enough args provided')
    let ValidUsername = null;
    let ValidEmail = null;

    if(username) {
        ValidUsername = await UserNameExists(username);
    }
    if(email) {
        ValidEmail = await EmailExists(email);
    }
    if(ValidUsername && ValidEmail) return ValidUsername;
    return null;
}

async function CreateNewUser(args){
    return await CreateUser(args)
}

module.exports = {
    ValidateUserExists,
    CreateNewUser
}

I am expecting for it to throw this response

if(username === existingUser.username) 
return res.status(400).json({error:`Username ${username} is already taken`});

if(email === existingUser.email) return res.status(400).json({error:`Email is already taken`});

Am I using await and async wrong way? Can someone please enlighten me

Ad

Answer

Your problem was that your function callback you was sending to asyncHandler( wasn't marked as async, so any functions your using inside cannot use await.

Assuming your asyncHandler is expecting a promise, doing asyncHandler(async (req,res) => { should fix this.

As a side note, looking at your code there is a fundamental logic problem you might want to think about. Doing UserNameExists / EmailExits & then CreateUser, in a multi-user environment in theory could still allow the same user & email to be stored. Most databases have something called transaction locks to prevent this happening.

Ad
source: stackoverflow.com
Ad