使用JSON.strgify无法对错误进行字符串化吗?

使用JSON.strgify无法对错误进行字符串化吗?

再现问题

在试图使用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并在各种浏览器中运行它。ChromeVersion 28给了我同样的结果,有趣的是,Firefox至少尝试了一下,但忽略了这个信息:

>>> JSON.stringify(error); // Firebug, Firefox 23{"fileName":"debug eval code","lineNumber":1,"stack":"@debug eval code:1\n"}

替换函数

然后我看了看错误原型..它显示了原型包含的方法,如托斯特林到源..我知道函数不能被压缩,所以我包括了一个替换函数当调用JSON.strgify来删除所有函数时,却意识到它也有一些奇怪的行为:

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

它似乎不像通常那样在对象上循环,因此我无法检查键是否是函数而忽略它。

问题

是否有任何方法将本机错误消息压缩为JSON.stringify?如果没有,为什么会发生这种行为?

绕过这件事的方法

  • 坚持使用简单的基于字符串的错误消息,或者创建个人错误对象,而不依赖于本机错误对象。
  • 拉力特性:

    JSON.stringify({ message: error.message, stack: error.stack })


森栏
浏览 516回答 3
3回答

撒科打诨

您可以定义Error.prototype.toJSON检索平原Object表示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"}使用Object.defineProperty()加toJSON而不是enumerable财产本身。关于修改Error.prototype,同时toJSON()可能不会被定义为Error特别是,该方法仍是标准化的。对于一般的对象(参见:步骤3)。因此,碰撞或冲突的风险是最小的。不过,为了完全避免,JSON.stringify()氏replacer参数可改为:function replaceErrors(key, value) {     if (value instanceof Error) {         var error = {};         Object.getOwnPropertyNames(value).forEach(function (key) {             error[key] = value[key];         });         return error;     }     return value;}var error = new Error('testing');error.detail = 'foo bar';console.log(JSON.stringify(error, replaceErrors));

婷婷同学_

修改乔纳森的好答案以避免猴子打补丁:var stringifyError = function(err, filter, space) {   var plainObject = {};   Object.getOwnPropertyNames(err).forEach(function(key) {     plainObject[key] = err[key];   });   return JSON.stringify(plainObject, filter, space);};var error = new Error('testing');error.detail = 'foo bar';console.log(stringifyError(error, null, '\t'));

DIEA

因为没有人在谈论为什么一部分,我来接。为什么这样JSON.stringify返回空对象?> JSON.stringify(error);'{}'回答从…的文件JSON.strgify(),对于所有其他对象实例(包括Map、Set、WeakMap和WeakSet),只有它们的可枚举属性才会被序列化。和Error对象没有可枚举的属性,这就是它打印空对象的原因。
打开App,查看更多内容
随时随地看视频慕课网APP