दिलचस्प पोस्ट
FileDialog काम नहीं करता है Verilog – फ़्लोटिंग पॉइंट गुणन कैसे एक पुनरावर्ती regexp अजगर में लागू किया जा सकता है? नेविगेशन ड्रॉवर के टुकड़े के बजाय गतिविधियों को बदलने के लिए सी ++: "वापसी" कथन के साथ प्रतिलिपि से बचना क्या एक इकाई निकाय अनुरोध एक HTTP डिलीएट अनुरोध के लिए है? सी # में दो सरणियों का सहसंबंध एक सूची <X> से सूची के लिए <Y> कास्टिंग के लिए छोटे सिंटैक्स? ब्राउज़र के प्रोटोकॉल संचालकों को कैसे पता चलेगा? Qt में विगेट्स पहलू अनुपात कैसे बनाए रखा जाए? इसी मॉडल में अन्य फ़ील्ड के आधार पर Django मॉडल फ़ील्ड डिफ़ॉल्ट आधार आईओएस कस्टम टैबबार CSS त्रिकोण कैसे काम करते हैं? उन फ़ाइलों को अनदेखा करें जो पहले से ही एक Git रिपॉजिटरी के लिए प्रतिबद्ध हैं जावा में स्ट्रिंग्स को प्रारूपित करने के तरीके

JSON.stringify का उपयोग करते हुए त्रुटि को स्ट्रिंग करना संभव नहीं है?

समस्या का पुनरुत्पादन

वेब सॉकेट्स का उपयोग करने के दौरान त्रुटि संदेशों को पार करने की कोशिश करते समय मैं एक समस्या में चल रहा हूं मैं इस मुद्दे को दोहरा सकता हूं JSON.stringify उपयोग मैं व्यापक दर्शक को पूरा करने के लिए 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); '{}' 

समस्या यह है कि मैं एक खाली वस्तु के साथ समाप्त होता है

मैंने क्या कोशिश की है

ब्राउज़र्स

मैंने पहले नोड। जेएस को छोड़ने और इसे विभिन्न ब्राउज़रों में चलाने की कोशिश की। क्रोम संस्करण 28 मुझे एक ही परिणाम देता है, और दिलचस्प रूप से पर्याप्त, फ़ायरफ़ॉक्स कम से कम एक प्रयास करता है लेकिन संदेश छोड़ दिया है:

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

रिप्लेसर फंक्शन

मैंने तब त्रुटि को देखा। प्रोटोकाट यह दर्शाता है कि प्रोटोटाइप में ऐसे तरीकों जैसे स्ट्रिंग और टू सोर्स हैं । यह जानकर कि फ़ंक्शंस तंग नहीं हो सकते, मैं सभी फ़ंक्शन को निकालने के लिए JSON.stringify पर कॉल करते समय एक replacer फ़ंक्शन शामिल करता था, लेकिन फिर महसूस किया कि यह भी कुछ अजीब व्यवहार था:

 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 करने का कोई तरीका है? यदि नहीं, तो यह व्यवहार क्यों होता है?

इस के आसपास होने के तरीके

  • साधारण स्ट्रिंग-आधारित त्रुटि संदेशों के साथ रहें या व्यक्तिगत त्रुटि ऑब्जेक्ट बनाएं और मूल त्रुटि ऑब्जेक्ट पर भरोसा मत करें।
  • गुणों को खींचें: 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

स्वीकृत जवाब इस समस्या के लिए एक समाधान प्रदान करता है।

Solutions Collecting From Web of "JSON.stringify का उपयोग करते हुए त्रुटि को स्ट्रिंग करना संभव नहीं है?"

Error प्रतिनिधित्व करने के लिए एक सादा Object को पुनर्प्राप्त करने के लिए आप Error.prototype.toJSON को परिभाषित कर सकते हैं:

 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() का प्रयोग करते हुए Object.defineProperty() को इसके बिना एक 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)); 
 JSON.stringify(err, Object.getOwnPropertyNames(err)) 

काम करने लगता है

[ / u / ub3rgeek पर / r / javascript द्वारा एक टिप्पणी से ] और नीचे felixfbecker की टिप्पणी

बंदर पट्टी से बचने के लिए जोनाथन के महान उत्तर को संशोधित करना:

 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')); 

आप उन गैर-गणना योग्य गुणों को फिर से भी परिभाषित कर सकते हैं, जिनकी गणना महत्वपूर्ण है।

 Object.defineProperty(Error.prototype, 'message', { configurable: true, enumerable: true }); 

और शायद संपत्ति भी stack हो

ऊपर दिए गए उत्तर में कोई भी त्रुटि के प्रोटोटाइप पर मौजूद गुणों को ठीक तरह से क्रमबद्ध नहीं कर रहा था (क्योंकि getOwnPropertyNames() में इनहेरिट की गई प्रॉपर्टी शामिल नहीं हैं)। मैं भी सुझावों में से एक उत्तर की तरह संपत्तियों को फिर से परिभाषित करने में सक्षम नहीं था

यह मेरे साथ आए हल है – यह लैंडशिप का उपयोग करता है, लेकिन आप उन कार्यों के जेनेरिक संस्करणों के साथ रियास को बदल सकते हैं।

  function recursivePropertyFinder(obj){ if( obj === Object.prototype){ return {}; }else{ return _.reduce(Object.getOwnPropertyNames(obj), function copy(result, value, key) { if( !_.isFunction(obj[value])){ if( _.isObject(obj[value])){ result[value] = recursivePropertyFinder(obj[value]); }else{ result[value] = obj[value]; } } return result; }, recursivePropertyFinder(Object.getPrototypeOf(obj))); } } Error.prototype.toJSON = function(){ return recursivePropertyFinder(this); } 

यहां मैंने Chrome में किया परीक्षण है:

 var myError = Error('hello'); myError.causedBy = Error('error2'); myError.causedBy.causedBy = Error('error3'); myError.causedBy.causedBy.displayed = true; JSON.stringify(myError); {"name":"Error","message":"hello","stack":"Error: hello\n at <anonymous>:66:15","causedBy":{"name":"Error","message":"error2","stack":"Error: error2\n at <anonymous>:67:20","causedBy":{"name":"Error","message":"error3","stack":"Error: error3\n at <anonymous>:68:29","displayed":true}}} 

इसके लिए एक महान नोड। जेएस पैकेज है: serialize-error

यह अच्छी तरह से नेस्टेड एरर ऑब्जेक्ट्स भी संभालती है, जो वास्तव में मुझे मेरे प्रोजेक्ट में बहुत ज़रूरी है।

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