无法使用JSON.stringify将错误字符串化吗?

重现问题

尝试使用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"}

替代功能

I then looked at the Error.prototype. It shows that the prototype contains methods such as toString and toSource. Knowing that functions can't be stringified, I included a replacer function when calling JSON.stringify to remove all functions, but then realized that it too had some weird behavior:

var error = new Error('simple error message');
JSON.stringify(error, function(key, value) {
    console.log(key === ''); // true (?)
    console.log(value === error); // true (?)
});

It doesn't seem to loop over the object as it normally would, and therefore I can't check if the key is a function and ignore it.

The Question

Is there any way to stringify native Error messages with JSON.stringify? If not, why does this behavior occur?

Methods of getting around this

  • Stick with simple string-based error messages, or create personal error objects and don't rely on the native Error object.
  • Pull properties: JSON.stringify({ message: error.message, stack: error.stack })

Updates

@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

接受的答案提供了解决此问题的方法。

西里米亚2020/03/18 18:10:55

我正在为日志追加程序处理JSON格式,最终在这里试图解决类似的问题。过了一会儿,我意识到我可以让Node来工作:

const util = require("util");
...
return JSON.stringify(obj, (name, value) => {
    if (value instanceOf Error) {
        return util.format(value);
    } else {
        return value;
    }
}
达蒙神奇2020/03/18 18:10:55
JSON.stringify(err, Object.getOwnPropertyNames(err))

似乎有效

[ 摘自/ u / ub3rgeek在/ r / javascript上的评论]和felixfbecker的评论(下方)

斯丁AJinJin2020/03/18 18:10:55

有一个伟大的Node.js包为:serialize-error

它甚至可以很好地处理嵌套的Error对象,这实际上是我在项目中急需的。

https://www.npmjs.com/package/serialize-error