0

I have got the following example

module.exports = (err, req, res, next) => {
  err.statusCode = err.statusCode || 500;
  err.status = err.status || 'error';

  if (process.env.NODE_ENV === 'development') {
    sendDevError(err, req, res);
  } else if (process.env.NODE_ENV === 'production') {
    console.log(err); // { message: 'test message', statusCode: '404', status: 'failed' }
    let error = { ...err };
    console.log(error); // { statusCode: '404', status: 'failed' }
    // error.message = err.message;
    if (error.name === 'CastError') error = handleCastErrorDB(error);
    if (error.code === 11000) error = handleDuplicateFieldsDB(error);
    if (error.name === 'ValidationError')
      error = handleValidationErrorDB(error);
    if (error.name === 'JsonWebTokenError') error = handleJWTError();
    if (error.name === 'TokenExpiredError') error = handleJWTExpiredError();
    sendProdError(error, req, res);
  }
};

The magic comes along with object spread. When im cloning err object that for some reason message property is missing in my clone object. I solved this by just putting error.message = err.message after object spread. But this approach is not what im trying to achieve. Could someone explain me how object spread is working under the hood? And what could i do to play around this weird bug?

kuklyy
  • 316
  • 3
  • 13

1 Answers1

3

I think you're asking why message isn't copied when you do this:

let error = { ...err };

The answer is that property spread only processes own, enumerable properties of the source object. The message property of Error instances is an inherited property, not an "own" property.

Here's an example showing that distinction in action:

const p = {message: "value"};
const c = Object.create(p);
c.own = "prop";
console.log(c.message);                   // "value";
console.log("message" in c);              // true
console.log(c.hasOwnProperty("message")); // false

console.log({...c}); // {"own": "prop"}

// Copy message onto the object
c.message = c.message;
console.log({...c}); // {"own": "prop", "message": "value"}
.as-console-wrapper {
    max-height: 100% !important;
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875