Is it not possible to stringify an Error using JSON.stringify?

You can define a Error.prototype.toJSON to retrieve a plain Object representing the Error:

if (!('toJSON' in Error.prototype))
Object.defineProperty(Error.prototype, 'toJSON', {
    value: function () {
        var alt = {};

        Object.getOwnPropertyNames(this).forEach(function (key) {
            alt[key] = this[key];
        }, this);

        return alt;
    },
    configurable: true,
    writable: true
});
var error = new Error('testing');
error.detail = 'foo bar';

console.log(JSON.stringify(error));
// {"message":"testing","detail":"foo bar"}

Using Object.defineProperty() adds toJSON without it being an enumerable property itself.


Regarding modifying Error.prototype, while toJSON() may not be defined for Errors specifically, the method is still standardized for objects in general (ref: step 3). So, the risk of collisions or conflicts is minimal.

Though, to still avoid it completely, JSON.stringify()'s replacer parameter can be used instead:

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

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

        return error;
    }

    return value;
}

var error = new Error('testing');
error.detail = 'foo bar';

console.log(JSON.stringify(error, replaceErrors));

JSON.stringify(err, Object.getOwnPropertyNames(err))

seems to work

[from a comment by /u/ub3rgeek on /r/javascript] and felixfbecker's comment below