Brett East
Brett East

Reputation: 4322

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.

Upvotes: 4

Views: 2900

Answers (2)

Abdel
Abdel

Reputation: 97

Another way of solving this is by converting the error to string.

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

Upvotes: 0

Brett East
Brett East

Reputation: 4322

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.

Upvotes: 15

Related Questions