Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 663
Himkar Dwivedi Avatar asked Nov 16 '17 12:11

Himkar Dwivedi


People also ask

Does Res json () Send?

json() Function. The res. json() function sends a JSON response. This method sends a response (with the correct content-type) that is the parameter converted to a JSON string using the JSON.

What does Res send () do?

send() Send a string response in a format other than JSON (XML, CSV, plain text, etc.). This method is used in the underlying implementation of most of the other terminal response methods.

Should I use Res send or RES json?

There is no actual difference between res. send and res. json, both methods are almost identical.

What is the use of Express json ()?

json() is a built-in middleware function in Express. This method is used to parse the incoming requests with JSON payloads and is based upon the bodyparser. This method returns the middleware that only parses JSON and only looks at the requests where the content-type header matches the type option.


1 Answers

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!

like image 130
Curt Keisler Avatar answered Sep 25 '22 11:09

Curt Keisler