Tuesday, November 15, 2022

[FIXED] How to return error message objects to the client in Express?

Issue

I have this block of code:

router.post('/users/login', async (req, res) => {
  try {
    const { email, password } = req.body
    const user = await User.findByCredentials(email, password)
    console.log(user) //false
    if (!user) {
      throw new Error('Login failed! Check authentication credentials')
    }
    const token = await user.generateAuthToken()
    res.status(200).json({ user, token })
  } catch (err) {
    console.log(err) //Error: Login failed! Check authentication credentials at C:\Users...
    res.status(400).json(err)
  }
})

It works all fine until there is no Error. When error occur (user is false) in Postman I have only empty object returned {}. Also with res.status(400).json({error: err}) it gives me { "err": {} }.

I want to receive object like this { "error": "Login failed! Check authentication credentials" }


Solution

JSON.stringify can't capture non-enumerable object properties as jfriend00 mentions but there are some pretty direct solutions that seem worth mentioning.

One way is to create the correct object yourself using the err.message property, which contains the string provided to the Error constructor:

app.get("/foo", (req, res) => {
  try {
    throw Error("hello world");
  }
  catch (err) {
    res.status(400).json({error: err.message});
  }
});

Another approach if you really can't touch your res.json call is to throw an object set up how you like it. I don't like this because you lose stack trace information (see: 1, 2, 3), but it exists:

app.get("/foo", (req, res) => {
  try {
    throw {error: "hello world"};
  }
  catch (err) {
    res.status(400).json(err);
  }
});

In both cases, the client sees

{
    error: "hello world"
}


Answered By - ggorlen
Answer Checked By - Marie Seifert (PHPFixing Admin)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.