問題の再現
JSON.stringify
Web ソケットを使用してエラー メッセージを渡そうとすると、問題が発生します。より幅広いユーザーに対応するために、私が直面している問題を再現できます。
// 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"}
置換関数
私はその後、エラー.プロトタイププロトタイプには次のようなメソッドが含まれていることがわかります。そしてソースへ関数は文字列化できないことを知っていたので、置換関数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 })
アップデート
@レイ・トールコメントで私が見てみることを提案したプロパティ記述子なぜそれが機能しないのかは明らかです。
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
。
承認された回答は、この問題の回避策を提供します。
ベストアンサー1
JSON.stringify(err, Object.getOwnPropertyNames(err))
効きそうだ
[/r/javascript の /u/ub3rgeek のコメントより] と felixfbecker のコメント
これが必要な理由については、「Sanghyun Lee」の回答も参照してください。