重现问题
我在尝试使用 Web 套接字传递错误消息时遇到了问题。我可以复制我面临的问题JSON.stringify来迎合更广泛的受众:
// node v0.10.15
> var error = new Error('simple error message');
    undefined
> error
    [Error: simple error message]
> Object.getOwnPropertyNames(error);
    [ 'stack', 'arguments', 'type', 'message' ]
> JSON.stringify(error);
    '{}'
问题是我最终得到了一个空对象。
我试过的
浏览器
我首先尝试离开 node.js 并在各种浏览器中运行它。Chrome 版本 28 给了我相同的结果,有趣的是,Firefox 至少做了一次尝试,但遗漏了消息:
>>> JSON.stringify(error); // Firebug, Firefox 23
{"fileName":"debug eval code","lineNumber":1,"stack":"@debug eval code:1\n"}
替换功能
然后我查看了Error.prototype。它表明原型包含诸如toString和toSource 之类的方法。明知功能不能被字符串化,我包括一个替代品函数调用JSON.stringify时卸下的所有功能,但后来意识到它也有一些怪异的行为:
var error = new Error('simple error message');
JSON.stringify(error, function(key, value) {
    console.log(key === ''); // true (?)
    console.log(value === error); // true (?)
});
它似乎不像往常那样循环遍历对象,因此我无法检查键是否为函数并忽略它。
问题
有没有办法用字符串化本机错误消息JSON.stringify?如果不是,为什么会发生这种行为?
解决这个问题的方法
- 坚持使用简单的基于字符串的错误消息,或创建个人错误对象,不要依赖本机 Error 对象。
 - 拉属性: 
JSON.stringify({ message: error.message, stack: error.stack }) 
更新
@Ray Toal在评论中建议我查看属性描述符。现在很清楚为什么它不起作用:
var error = new Error('simple error message');
var propertyNames = Object.getOwnPropertyNames(error);
var descriptor;
for (var property, i = 0, len = propertyNames.length; i < len; ++i) {
    property = propertyNames[i];
    descriptor = Object.getOwnPropertyDescriptor(error, property);
    console.log(property, descriptor);
}
输出:
stack { get: [Function],
  set: [Function],
  enumerable: false,
  configurable: true }
arguments { value: undefined,
  writable: true,
  enumerable: false,
  configurable: true }
type { value: undefined,
  writable: true,
  enumerable: false,
  configurable: true }
message { value: 'simple error message',
  writable: true,
  enumerable: false,
  configurable: true }
关键:enumerable: false。
接受的答案提供了解决此问题的方法。