1

I’m attempting to create custom error objects in Node that use Error as the prototype and then to return these errors to the client via the express res.json() method. I can create an instance of a custom error, set it’s properties but when I call res.json(), the stack property is missing. I believe this is due to JSON.stringify() not following prototypes?

I can’t see a way of creating custom error objects with an arbitrary number of properties and then use JSON.stringify() on these objects to return all the properties and the base class / superclass Error stack property. Please help! An example is below:

(function (customErrorController) {


    function CustomError() {

        this.name = 'CustomError'; // String
        this.message = null; // String
        this.errorCode = null; // String
        // this.stack exists as CustomError inherits from Error
    }

    CustomError.prototype = new Error();


    customErrorController.init = function (app) {

        app.get('/test', function (req, res) {

            var customError = new CustomError();
            customError.message = 'The Message';
            customError.errorCode = 'Err001';

            console.log(customError.stack); // This logs the stack fine

            res.json(customError); // The stack is missing when outputting the object as JSON

        });
    };

})(module.exports);
Jon
  • 83
  • 3
  • 10
  • 2
    You've got that right, JSON.stringify does **not** stringify the prototypes. – adeneo Aug 18 '14 at 13:13
  • http://stackoverflow.com/questions/12369543/why-is-json-stringify-not-serializing-prototype-values – adeneo Aug 18 '14 at 13:16
  • Notice that you shouldn't print error stacks to the user, but log them into a serverside file and just respond with a 501 code. – Bergi Aug 18 '14 at 13:27
  • Also, you currently are printing the *wrong* stack - it is created when `new Error`, not when `new CustomError` is called. Have a look at https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi – Bergi Aug 18 '14 at 13:29
  • The solution to this can be found in [this answer](http://stackoverflow.com/questions/18391212/is-it-not-possible-to-stringify-an-error-using-json-stringify#answer-18391400). – mekwall Aug 18 '14 at 14:00
  • Use an existing module: https://github.com/Mitica/errod – dumitru May 06 '15 at 20:45

1 Answers1

1

Thanks for the comments. From these and from a bit more digging, I’m now using the following code to create custom errors and have the correct stack on the stack property return after calling res.json() with the error:

// Redefine properties on Error to be enumerable
Object.defineProperty(Error.prototype, 'message', { configurable: true, enumerable: true });
Object.defineProperty(Error.prototype, 'stack', { configurable: true, enumerable: true });


(function (customErrorController) {

    function CustomError(message, errorCode) {

        Error.captureStackTrace(this, CustomError);

        this.name = 'CustomError'; // String
        this.message = message; // String
        this.errorCode = errorCode; // String
    }

    CustomError.prototype = Object.create(Error.prototype);

    customErrorController.init = function (app) {

        app.get('/test', function (req, res) {

            var customError = new CustomError('The Message', 'Err001');
            res.json(customError); // The stack property is now included

        });
    };

})(module.exports);
Jon
  • 83
  • 3
  • 10