Himkar Dwivedi
Himkar Dwivedi

Reputation: 251

Express Js not sending error object on res.json()

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.

Upvotes: 8

Views: 3987

Answers (1)

Curt Keisler
Curt Keisler

Reputation: 178

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!

Upvotes: 5

Related Questions