1

This is the code:

router.post("/form", async (req, res) => {
  try {
    let { name, email, password } = req.body;
    let user = await User.create({
      name,
      email,
      password,
    });

    if (!user) return res.status(501).send("Something went wrong");
    let token = await user.getSignedToken();
    console.log(token); //Server logs this

user.emailToken = await user.verifyEmail();// This property is not being added in the saved mongodb document. It should, but again idk why it's not

    await user.save({ validateBeforeSave: false });
    console.log(user); // Server doesn't log this
    const options = {
      expires: new Date(
        Date.now() + process.env.JWT_COOKIE_EXPIRE * 24 * 60 * 60 * 1000
      ),
    };
    console.log(options); // Server doesn't log this
    res.cookie("token", token, options);
    res.send("Check email for activation");
  } catch (ex) {
    res.send(ex);
  }
});

Below is the verifyEmail method (in userSchema.. I'm using mongoose):

userSchema.methods.verifyEmail = async function () {
  let emailToken = this._id + crypto.randomBytes(10).toString("hex");
  let emailTokenHashed = await crypto
    .createHash("sha256")
    .update(passwordToken)
    .digest("hex");
  this.emailToken = emailTokenHashed;

  return emailToken;
};

Now, it should send "Check email for activation", right? But, it's sending an empty response object. Also, if you see in the code, the server is logging only one console.log (i.e. the first console.log). But, it is sending a cookie (I checked via postman). So, what's the issue here?

3
  • You do not need to await crypto while creating a hash. nodejs.org/dist/latest-v12.x/docs/api/… Commented Jul 30, 2020 at 21:21
  • It's not the answer to your question, but why not just call this.save() in your Schema method instead of doing user.emailToken = await user.verifyEmail() and then the saving? Or you could also just do await user.verifyEmail() without setting it to user.emailToken because it's already set in the Schema method or isn't it? Am I missing something here? Commented Jul 30, 2020 at 21:27
  • @jfriend00 no it doesn't. it's sending an empty object as response Commented Jul 30, 2020 at 21:29

1 Answer 1

1

This code sends res.send("Check email for activation"); or res.send(ex);. Since you say that:

console.log(options); // Server doesn't log this

then one of your await statements must be hitting a rejected promise and sending you to the catch. Add console.log(ex) right before res.send(ex) to see what the error is so you have this:

} catch (ex) {
    console.log("got error", ex);
    res.send(ex);
}

And, then see what you get in the log.

In general you never want to send an error object directly because most of its properties are non-enumerable so they won't get sent as JSON and that may make the error object completely empty when it gets converted to JSON and thus isn't useful to the client at all. Instead, log the error on your server and send a 500 status:

res.sendStatus(500);

Or, if you want to send an error object construct your own error object with regular, enumerable properties and send that.

Anyway, once you add the console.log(ex) to your server, it should tell you what the actual rejected promise is and that will show you what's going wrong with the request. ALWAYS log errors on the server to help you see and solve problems like this.

Sign up to request clarification or add additional context in comments.

10 Comments

first of all, I'm receiving an empty object as response. Secondly, I tried console.log(ex) but it doesn't log any exception
@Zain763 - What exactly does console.log(ex) log? Your code only has two places you're sending a response. One sends a string, the other sends an object. If you're getting an object back from the response, logic would say that you're hitting the code path that sends the object. You need to debug why that is.
console.log(ex) is not logging anything at all. That's what I don't understand. It doesn't log 2 console log statements. It doesn't log exception. It doesn't send the desired response but it is setting the cookie. That's the problem that I don't understand. Been working on it for hours.
@Zain763 - Then, either await user.verifyEmail(); or await user.save({ validateBeforeSave: false }); must be rejecting/throwing. You have to figure out which one is and capture the error message from it to see why. You can surround each with their own try/catch with their own separate error logging to make sure their error gets output and so you can see which one is getting hit.
@Zain763 - Please also change your code so you're not doing res.send(ex); in the catch because that isn't going to be useful to the caller. You should send an error status.
|

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.