Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not able to respond to custom error message sent from express

This problem annoys me, because I know it has something to do with me not understanding the issue properly - which makes it really hard to track down answers for, despite spending hours reading and trying different things.

My question/problem is this, I am saving a user to a mongodb database when they signup, my schema doesn't allow for duplicate emails, and sends me back an error. I am able to console log the error in the terminal, but I am having problems sending it back to the client. Or I'm having a problem doing something with it, if it comes back, I'm not too sure where in those two steps I am losing access to the error message.

Here is my POST route for saving the user:

router.post('/users', (req, res) => {
  let body = _.pick(req.body, ['email', 'password']);
  let user = new User(body);

  user.save().then(() => { // this all works and will save the user, if there are no errors
    return user.generateAuthToken();
  }).then((token) => {
    res.header('Authorization', `Bearer ${token}`).send(user);
  }).catch((err) => { // This is where my problem is
    console.log(err); // This will log the mongodb error here, about duplicate emails
    res.status(500).send(err); // I'm trying to send the mongodb error message back to the client to display it on the screen (I will handle making the message friendly to read, once I can get this to work)
  });
});

So my catch is getting the mongo error, and then I try to respond with it, by sending it to the client.

Here is my client side code:

axios({
  method: 'post',
  url: '/auth/users',
  headers: {
    'Content-Type': 'application/json'
  },
  data: {
    email,
    password
  }
}).then((res) => {
  console.log('this is the response', res);
  if (res.status === 200) {
    var authToken = res.headers.authorization.split(' ')[1];
    authenticateUser(authToken);
    this.props.history.replace('/dashboard');
  } // This all works fine for a signup with no errors
}).catch((err) => {
  console.log('Signup error:', err);
  // I am expecting the above line of code to log the long Mongodb 
  // error message that I am sending back in my res.status(500).send(err)
  // catch call from the server, but instead all I am getting is
  // "Signup error: Error: Request failed with status code 500"
});

Either I'm not sending the error correctly, or I'm not handling it correctly when it comes back, but I have no idea which it is or why.

I can't even send back res.status(500).send('some string here') and access that string.

Thanks

Update

So I just checked in postman, by sending a POST that could cause the error, and I am getting the correct response sent through.

My server catch actually looks like this:

.catch((err) => {
  res.status(500).send({message: err.message});
});

And the postman response body looks like this:

{
  "message": "E11000 duplicate key error collection: authBoilerplate.users index: email_1 dup key: { : \"[email protected]\" }"
}

So I'm just not handling it correctly in my client side code, still at a loss though.

like image 795
Brett East Avatar asked Dec 07 '22 17:12

Brett East


1 Answers

Thanks everyone, I was able to find the answer to my question, so I'm posting it here in the hope that it might help someone else.

I was definitely sending my custom error message back, I just wasn't handling it properly on the client side.

When I was using a catch call on the client and logging the error, I was expecting to see everything included in the error. It turns out that the error comes back with a response property error.response, and that is where all the messaging is.

So changing my catch call to this:

axios(//... send post in here)
.then(// ... same as in my question)
.catch((err) => {
  console.log('error', err);
  console.log('error response', err.response); // this is where the actual error response message is error.response.message
});

resulted in logging the stack trace and the error response:

error Error: Request failed with status code 500
    at createError (eval at <anonymous> (bundle.js:541), <anonymous>:16:15)
    at settle (eval at <anonymous> (bundle.js:847), <anonymous>:18:12)
    at XMLHttpRequest.handleLoad (eval at <anonymous> (bundle.js:520), <anonymous>:77:7)
error response Object {data: Object, status: 500, statusText: "Internal Server Error", headers: Object, config: Object…}

I was still expecting to be able to see that I had access to that 'response' property by logging just the error, so if anyone has any insight into that, it would be great to include in the comments.

like image 133
Brett East Avatar answered Dec 11 '22 07:12

Brett East