[解決済み] JSON.stringifyでErrorを文字列化することはできないのでしょうか?
質問
問題の再現
ウェブソケットを使用してエラーメッセージを渡そうとすると、ある問題にぶつかるんだ。私が直面している問題は、以下の方法で再現できます。
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 . このプロトタイプには、次のようなメソッドが含まれていることがわかります。 文字列 と ソース . 関数が文字列化できないことを知っていたので、私はこの関数に 置き換え機能 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 })
更新情報
レイ・トール コメントで提案されたので、見てみると プロパティ記述子 . なぜうまくいかないのか、理由が明らかになりました。
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
.
Accepted answer は、この問題の回避策を提供します。
解決方法を教えてください。
を定義することができます。
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()
's
replacer
パラメータ
を代わりに使用することができます。
function replaceErrors(key, value) {
if (value instanceof Error) {
var error = {};
Object.getOwnPropertyNames(value).forEach(function (propName) {
error[propName] = value[propName];
});
return error;
}
return value;
}
var error = new Error('testing');
error.detail = 'foo bar';
console.log(JSON.stringify(error, replaceErrors));
関連
-
fetch ネットワークリクエストラッパーの説明例
-
[解決済み】GETできない / Nodejsエラー
-
[解決済み】JavaScriptでインラインIF文の書き方は?
-
[解決済み】「.addEventListener is not a function」なぜこのエラーが発生するのか?
-
[解決済み] let "と "var "の使い分けは?
-
[解決済み] とは何ですか! (not not)演算子とは何ですか?
-
[解決済み] JavaScriptでJSONをきれいに印刷する
-
[解決済み] 私のJavaScriptコードは "No 'Access-Control-Allow-Origin' header is present on requested resource "というエラーを受け取りますが、Postmanはそうならないのはなぜですか?
-
[解決済み] URLを新しいタブで開く(新しいウィンドウではない)
-
[解決済み] forEachループでasync/awaitを使用する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
要素ツリー制御によるvueTreeテーブル
-
JSアレイループと効率解析の比較
-
WeChatアプレット用ユニアプリによるグローバルシェアリング
-
vueが定義するプライベートフィルタと基本的な使い方
-
Vueのイベント処理とイベントモディファイアの解説
-
[解決済み】Node Version Manager のインストール - nvm コマンドが見つかりません。
-
[解決済み】TypeErrorの解決方法。未定義またはヌルをオブジェクトに変換できない
-
[解決済み】ERROR エラーです。スイッチのname属性が指定されていないフォームコントロールの値アクセッサがない
-
[解決済み】「.addEventListener is not a function」なぜこのエラーが発生するのか?
-
JavaScriptのgetElementById()メソッド入門