0

I build a register page using React as Frontend, and Node Js as backend. However, when I try to check the delicate username. Axios from the Frontend doesn't show any error. I have written the catch in many different ways. But I still cannot find where the problem is. Could anyone help me out? Thanks!

Frontend

const handleSubmit = async (event) => {
    event.preventDefault();
    
    if (handleValidation()) {
      await axios.post(registerRoute, {
        username,
        email,
        password,
      }).then((response) => {
        console.log(response);
      }).catch((error) => {
         if (error.response.status === 11000) {
          console.log(error.response.data);
         }
      })
      navigate("/");
    }
  };

Backend

module.exports.register = async (req, res, next) => {
   const { username, email, password } = req.body;

   if (!username || typeof username !== 'string') {
      return res.json({status: 'error', message: 'Invalid username'})
   }

    const usernameExit = await Users.findOne({username: username})
    if (usernameExit) {
       return res.status(11000).json({ message: "Username already exit" });
    }

   if (!password || typeof password !== 'string') {
      return res.json({status: 'error', message: 'Invalid password'})
   }

  try {
    const hashedPassword = await bcrypt.hash(password, 2); 
    const user = new Users({
      username,
      email,
      password: hashedPassword,
    });
    user.save();
    delete user.password;
    return res.json({ status: true, user });
  } catch (error) {
   if (error.code === 11000) {
      return res.status(11000).json({ message: "Username already exit" });
   }
  }
};

2 Answers 2

0

First things first. In your back end endpoint you need to add the word await in before saving the document since you're using async/await for this method.

await user.save();

Second, you won't be able to delete the user's password this way because this is a MongoDB document and not a JavaScript object. You can convert the document to be a JS object which was explained in this question below. After you convert it to a JS object then you do delete user.password, not before.

convert mongodb object to javascript object

Third, you should always follow the industry best practices and use one of the HTTPS codes based on the situation. This way you know that a MongoDB error code is coming from MongoDB and not your endpoint because you setup a different status code like 404 or 400 for any custom error handling that you are doing.

Here's the reference for the HTTPS codes - https://developer.mozilla.org/en-US/docs/Web/HTTP/Status

If you want to catch the status in Axios, you need to set the status like @Yozi mentioned and follow the approach below

return res.status(400).json({message: "Some message here", user});

This way Axios will catch the 400 status and throw an error in the console. If you customize the status like

res.json({status: 'error'});

You need to handle that differently in your front end. You can do something like

console.log(res.data.status === 'error');
Sign up to request clarification or add additional context in comments.

Comments

0
  1. return res.json({status: 'error', message: 'Invalid password'}) It returns status 200, which is not an error (axios know nothing about your status: "error" thing.
  2. status 11000 does not sound right to me. Normally it is something below 600. docs. In your case, I would use 422.

So, for all your errors add status(422) and check if it works.

6 Comments

11000 is a mongodb error - Duplicate key. You can see more here @Yozi github.com/Automattic/mongoose/issues/2284
@LeonardoNoronhaSantos I mean, it is ok to have 11000 in mongo, but you set 11000 for HTTP status code, it does not sound right. res.status(11000) here - I would use 422
I agree, you should never mix mongodb error codes with your own stuff.
@Yozi@LeonardoNoronhaSantos Thanks, guys. It works. However, I got one more question. After I set the HTTP status to 422. It will not show any error message on the server side. Do we need to show the error message on both Frontend and Backend? If it's necessary how can I console the same error on the server side too?
@DavidLew Yes, you handled the error in your backend code and it is not an exception anymore, so there are no additional messages. If you want to log this situation, you can use a simple console.log/console.warn/console.error, or (better) use something like Winston for better customizations
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.