当前位置: 首页 > 面试题库 >

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

杭志泽
2023-03-14
问题内容

重现问题

尝试使用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吗?如果没有,为什么会出现这种现象?

解决这个问题的方法

  • 坚持使用基于字符串的简单错误消息,或者创建个人错误对象,而不依赖于本地错误对象。
  • 拉属性: 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

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


问题答案:

您可以定义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专门针对s
进行定义,但通常该方法仍针对对象进行了标准化(参考:步骤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));


 类似资料:
  • 我在尝试使用web套接字传递错误消息时遇到了一个问题。我可以使用复制我面临的问题,以迎合更广泛的受众: 问题是我最终得到了一个空对象。 然后我看了看错误。原型。它表明原型包含toString和toSource等方法。知道函数不能被字符串化,我在调用json.stringify以删除所有函数时包含了一个替换器函数,但随后意识到它也有一些奇怪的行为: 它似乎没有像通常那样在对象上循环,因此我不能检查键

  • 问题内容: 我正在尝试将字符串解析为对象。我在下面的链接中查看了jQueryparseJSON文档, 我也包括了jquery库,所以我知道不是那样的。 到目前为止,这是我的代码 在Firebug中,出现以下错误: 我知道该解决方案很可能非常简单,但是我一直反复忽略它。 问题答案: 示例代码中的测试字符串不是有效的JSON: 现在,如果由于所有服务使该对象作为JSON字符串可用而执行所有操作,则jQ

  • ()中的ValueError回溯(最近一次调用)---- ~\Anaconda3\lib\site packages\sklearn\preprocessing\data.py in fit_transform(self,X,y)2017”““2018年返回所选的fit_transform(X,self.\u fit_transform- ~\Anaconda3\lib\site-包\skLear

  • 问题内容: 显示值时出现错误: 在php中,来自数据库($ thedate)的值为“ 2015-05-05 21:52:31.000” 我如何格式化它以便能够将它作为字符串显示在php页面上?当前,它显示错误“类DateTime的对象无法转换为字符串”。 问题答案: 您有一个对象,因此必须使用它来格式化输出,例如

  • 我需要本地化info.plist的两个键:和。所以我尝试创建一个名为info.plist.strings的新文件,然后我对其进行了本地化,但app总是显示存储在info.plist文件中的字符串。怎么了? 本地化值不存储在info.plist文件本身中。相反,您可以将特定本地化的值存储在名为infoplist.strings的字符串文件中。将此文件放置在用于存储相同本地化的其他资源的同一特定于语言

  • 将Android软件包*.apk拖放到AVD(Android虚拟设备)中会引发一个神秘的错误: > 我已经用最新的API(28)和一个与我自己的手机相匹配的AVD(牛轧糖7.0) APK是用Buildozer构建的python Kivy APK 我是Android开发的新手。我甚至不知道从哪里开始调试这个。有更好的日志吗? 如果我通过文件管理器将APK上载到AVD并安装,它也会失败。 但是,如果我