8
getUser: function(req, res){
    Model.getUser({}, function(error, models){
         if(error){
              let response = {
                  code: 'ERR0001',
                  msg: 'Facing issues while ....',
                  err: error
              }
              res.json(response);
          } else {
              res.json(models)
          }
     }
};

Above code is working fine for all positive scenarios. But for error scenario I am not getting complete error message instead it shows 'err: {}'.

I have already registered JSON parser with Express app object. Response I am getting in POSTMAN console in case error is

{
  code: 'ERR0001',
  msg: 'Facing issues while ....',
  err: {}
}

As per my requirement it should display something like:

{
  code: 'ERR0001',
  msg: 'Facing issues while ....',
  err: 'ERROR: whatever exception occurred on database operation...' 
}

Please help me to understand cause of this issue.

Himkar Dwivedi
  • 241
  • 3
  • 7
  • `console.log` the `error` before to check that it's what you expect. – Héctor Nov 16 '17 at 12:28
  • Moreover it's almost never just a string. If you just want the string of the error message, then call `error.toString()` on the assignment. – Neil Lunn Nov 16 '17 at 12:42
  • Thanks Neil, error.toString() solved 50% problem. now it returns main error message, but not full stack trace. Though its not required to be returned to front-end but still if there is any solution. – Himkar Dwivedi Nov 16 '17 at 15:46

1 Answers1

5

Express is stringifying your JSON response when you use res.json().

However, because the Error object doesn't get handled by JSON.stringify() as you would expect, you're not seeing the content of it; like the stack trace property for example.

For details on what's happening with JSON.stringify() and the Error object, check out this other stack overflow answer (I won't duplicate that here):

https://stackoverflow.com/a/18391400/2387067

So, using a variation of that answer, I will do this when I want to send back a Javascript Error object to the client from Express:

function replaceErrors(key, value) {
    if (value instanceof Error) {
        var error = {};

        Object.getOwnPropertyNames(value).forEach(function (key) {
            error[key] = value[key];
        });

        return error;
    }

    return value;
}

function getPureError(error) {
    return JSON.parse(JSON.stringify(error, replaceErrors));
}

and then make a call to it in my response like this:

res.status(500).json(getPureError(error));

The call to getPureError() stringifys the Error object and gets all of the properties because of the call to replaceErrors(). It then parses it back to a pure object. That pure object plays nicely with Express when the .json() call is made so you get all of your properties that you were expecting. It is a bit wasteful but you get the result you're looking for.

This results in my seeing the full, Error object; stack trace and all.

When I first encountered this problem, I was doing this:

res.status(500).json(error);

and I was getting back {} in my response on the server. It took me a bit of time to sort out what was happening there. I originally thought that I wasn't chaining that json() command incorrectly but I was. The actual problem was that the Error object doesn't behave like other objects with JSON.stringify() as described above.

I hope that helps you or at least someone else after all this time!

Curt Keisler
  • 138
  • 3
  • 9