जेएस में टाइपो त्रुटि के लिए जाँच


153

जेएस में यह जांचना संभव नहीं है कि किसी फ़ंक्शन को दिया गया तर्क वास्तव में 'त्रुटि' या त्रुटि का उदाहरण है।

उदाहरण के लिए, यह मान्य नहीं है:

typeof err === 'error'

चूंकि केवल 6 संभावित प्रकार हैं (तार के रूप में):

टाइपोफ़ ऑपरेटर एक स्ट्रिंग के रूप में जानकारी टाइप करता है। typeofरिटर्न के छह संभावित मूल्य हैं :

"संख्या", "स्ट्रिंग", "बुलियन", "ऑब्जेक्ट", "फ़ंक्शन" और "अपरिभाषित"।

MSDN

लेकिन क्या होगा अगर मेरे पास इस तरह का एक सरल उपयोग मामला है:

function errorHandler(err) {

    if (typeof err === 'error') {
        throw err;
    }
    else {
        console.error('Unexpectedly, no error was passed to error handler. But here is the message:',err);
    }
}

तो यह तय करने का सबसे अच्छा तरीका क्या है कि एक तर्क त्रुटि का एक उदाहरण है?

instanceofकिसी भी मदद के ऑपरेटर है?


10
हाँ, उपयोगerr instanceof Error
colecmc

2
@colecmc समस्याग्रस्त नहीं होगा यदि त्रुटि फ्रेम में कोड या किसी अन्य विंडो से आई होगी? उस स्थिति में अलग-अलग प्रोटोटाइप त्रुटि ऑब्जेक्ट होंगे, और उदाहरण के रूप में अपेक्षित रूप से काम नहीं करेगा। (देखें डेवलपर.
mozilla.org/en-US/docs/Web/JavaScript/Reference/…

@, मुझे ऐसा नहीं लगता। यह सिर्फ वास्तविक त्रुटि ऑब्जेक्ट को मान्य करेगा।
Colecmc

1
@colecmc, मुझे लगता है कि आप पाएंगे कि अगर आप errएक iframe में (कहते हैं) फेंक दिया है, लेकिन फिर इसे हाथ में लेने के लिए मूल विंडो में पास करें, तो आपको मिल जाएगा (err instanceof Error) === false। ऐसा इसलिए है क्योंकि iframe और उसकी मूल विंडो अलग, अलग Errorऑब्जेक्ट प्रोटोटाइप है। इसी तरह एक वस्तु जैसे obj = {};, जब एक अलग विंडो में चल रहे फ़ंक्शन को पास किया जाता है, तो चिल्लाना (obj instanceof Object)===false। (सबसे बुरी बात यह है कि IE में, यदि आप इसकी विंडो के नष्ट होने या नेविगेट होने के बाद ओब्जेक्ट का संदर्भ रखते हैं, तो ऑब्जेक्ट प्रोटोटाइप फोंस को कॉल करने की कोशिश करने से obj.hasOwnProperty()त्रुटियां होंगी!)
Doin

आप किस प्रकार की त्रुटि के लिए जाँच करते हैं? यानी catch((err)=>{if (err === ENOENT)रिटर्न में ENOENT is not definedत्रुटि?
ओल्डबॉय

जवाबों:


261

आप instanceofऑपरेटर का उपयोग कर सकते हैं (लेकिन नीचे चेतावनी देखें!)।

var myError = new Error('foo');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false

यदि जाँच हो रही है, तो त्रुटि अलग विंडो / फ्रेम / iframe में डाली गई है तो ऊपर काम नहीं करेगा। उस स्थिति में, instanceof Errorचेक एक Errorवस्तु के लिए भी गलत वापस आ जाएगा । उस स्थिति में, सबसे आसान तरीका डक-टाइपिंग है।

if (myError && myError.stack && myError.message) {
  // it's an error, probably
}

हालाँकि, डक-टाइपिंग गलत पॉज़िटिव उत्पन्न कर सकती है यदि आपके पास गैर-त्रुटि ऑब्जेक्ट हैं जिसमें गुण stackऔर messageगुण हैं।


1
@ AurélienRibon यह एक ReferenceErrorउदाहरण के साथ ठीक काम करता है । आप वैश्विक ReferenceErrorऑब्जेक्ट की जाँच कर रहे हैं । यह कोशिश करें: try { foo } catch (e) { console.log(e instanceof Error) }यह लॉग करता है true। यदि आप ReferenceErrorकिसी कारण से वैश्विक वस्तु की जांच करने की कोशिश कर रहे हैं , तो आप उपयोग कर सकते हैंError.isPrototypeOf(ReferenceError)
ट्रॉट

1
@ AurélienRibon (उह, यह भी, हाँ, यकीन नहीं था कि आप कह रहे हैं "यह एक रेफ़ररेंस के साथ काम नहीं करेगा" जो कि गलत है, या यदि आप केवल इंगित कर रहे हैं "यह वैश्विक रेफ़रेंस ऑब्जेक्ट के साथ काम नहीं करेगा" जो बिल्कुल सही है, हालाँकि मैं एक ऐसी स्थिति के साथ आने वाला एक कठिन समय आ रहा हूँ, जहाँ कोई भी जाँच कर रहा होगा, लेकिन यह उपयोग मामले की वैधता की तुलना में मेरी कल्पना की कमी के बारे में अधिक कह सकता है)।
Trott

हाहा, उस लोगों के बारे में खेद है, मैं सिर्फ एक अजीब त्रुटि में बंद था जहां मेरे सभी ReferenceErrorउदाहरणों के उदाहरण नहीं थे Error। यह vm.runInNewContext()नोड में कॉल के कारण था , जहां सभी मानक प्रोटोटाइप को फिर से परिभाषित किया गया है। मेरे सभी परिणाम मानक वस्तुओं के उदाहरण नहीं थे। मैं इस बारे में एसओ में देख रहा था, और इस धागे में गिर गया :)
ऑरेलियन रिबोन

1
आप कोशिश कर सकते हैंconst error = (err instanceof Error || err instanceof TypeError) ? err : new Error(err.message ? err.message : err);
आमिर अफरीदी

यदि आप इसकी instanceofएक विशेष प्रकार की त्रुटि की जाँच करते हैं, तो आप कैसे जाँचेंगे?
ओल्डबॉय

25

मैंने मूल प्रश्न पूछा - @ ट्रॉट का उत्तर निश्चित रूप से सबसे अच्छा है।

हालाँकि जेएस एक गतिशील भाषा होने के साथ और इतने सारे जेएस रनटाइम वातावरण होने के कारण, instanceofऑपरेटर विशेष रूप से फ्रंट-एंड डेवलपमेंट में विफल हो सकता है जब आइफ्रेम जैसी सीमाओं को पार कर रहा है। देखें: https://github.com/mrdoob/three.js/issues/5886

यदि आप बतख टाइपिंग से ठीक हैं, तो यह अच्छा होना चाहिए:

let isError = function(e){
 return e && e.stack && e.message;
}

मैं व्यक्तिगत रूप से वैधानिक रूप से टाइप की जाने वाली भाषाओं को पसंद करता हूं, लेकिन यदि आप एक गतिशील भाषा का उपयोग कर रहे हैं, तो यह एक गतिशील भाषा को गले लगाने के लिए सबसे अच्छा है, बजाय इसके कि यह एक सांख्यिकीय रूप से टाइप की गई भाषा की तरह व्यवहार करने के लिए मजबूर हो।

यदि आप थोड़ा अधिक सटीक प्राप्त करना चाहते हैं, तो आप ऐसा कर सकते हैं:

   let isError = function(e){
     return e && e.stack && e.message && typeof e.stack === 'string' 
            && typeof e.message === 'string';
    }

3
उपयोगिता फ़ंक्शन या लाइब्रेरी लिखते समय मैं इस संस्करण को पसंद करता हूं। यह उपयोगकर्ताओं को एक विशेष वैश्विक संदर्भ के लिए बाध्य नहीं करता है और JSON से वांछित त्रुटियों को भी ठीक से संभालता है।
18

धन्यवाद, हाँ, कई मामलों में, अगर यह एक त्रुटि की तरह दिखता है, तो हम एक त्रुटि की तरह व्यवहार कर सकते हैं। कुछ मामलों में बतख टाइपिंग पूरी तरह से स्वीकार्य है, कुछ मामलों में यह बिल्कुल भी स्वीकार्य नहीं है, इस मामले में, पूरी तरह से ठीक है।
अलेक्जेंडर मिल्स

मैंने डिबगर का उपयोग करके कुछ डिबगिंग की, और स्टैक और संदेश वास्तव में त्रुटि उदाहरणों पर केवल दो गैर-देशी गुण प्रतीत होते हैं।
अलेक्जेंडर मिल्स

1
@ आपको instanceofकुछ मामलों में ऑपरेटर के विफल होने के बारे में जानने में दिलचस्पी हो सकती है , लिंक किए गए लेख को देखें।
अलेक्जेंडर मिल्स

1
यह वास्तव में सरल तो यह विभिन्न प्रकार की त्रुटियों के साथ काम करता है (यानी Error, ReferenceError, ...)। और मेरे वातावरण में, instanceofकई परिस्थितियों में बुरी तरह विफल रहता है।
एलेक्सिस विल्के

10
var myError = new Error('foo');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false

केवल इसके साथ समस्या है

myError instanceof Object // true

इसका एक विकल्प कंस्ट्रक्टर संपत्ति का उपयोग करना होगा।

myError.constructor === Object // false
myError.constructor === String // false
myError.constructor === Boolean // false
myError.constructor === Symbol // false
myError.constructor === Function // false
myError.constructor === Error // true

हालांकि यह ध्यान दिया जाना चाहिए कि यह मैच बहुत विशिष्ट है, उदाहरण के लिए:

myError.constructor === TypeError // false

2

आप Object.prototype.toStringआसानी से जांच कर सकते हैं कि क्या वस्तु एक है Error, जो अलग-अलग फ्रेम के लिए भी काम करेगी।

function isError(obj){
    return Object.prototype.toString.call(obj) === "[object Error]";
}

function isError(obj){
    return Object.prototype.toString.call(obj) === "[object Error]";
}
console.log("Error:", isError(new Error));
console.log("RangeError:", isError(new RangeError));
console.log("SyntaxError:", isError(new SyntaxError));
console.log("Object:", isError({}));
console.log("Array:", isError([]));


1

आप किसी ऑब्जेक्ट के "वर्ग" की जांच करने के लिए obj.constructor.name का उपयोग कर सकते हैं https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Function_names_in_classes

उदाहरण के लिए

var error = new Error("ValidationError");
console.log(error.constructor.name);

उपरोक्त पंक्ति "त्रुटि" लॉग करेगी जो ऑब्जेक्ट का वर्ग नाम है। यह जावास्क्रिप्ट में किसी भी वर्ग के साथ इस्तेमाल किया जा सकता है, यदि वर्ग "नाम" नाम से जाने वाली संपत्ति का उपयोग नहीं कर रहा है


यह विश्वसनीय नहीं है जब कोड को कम करना और त्रुटि उपवर्गों का उपयोग करना है
felixfbecker

1

धन्यवाद @ आपके कोड के लिए, मैंने बस एक ही कोड का उपयोग किया और दूसरों के लाभ के लिए एक वास्तविक समय काम करने के उदाहरण के साथ जोड़ा।

<html>
<body >

<p>The **instanceof** operator returns true if the specified object is an instance of the specified object.</p>



<script>
	var myError = new Error("TypeError: Cannot set property 'innerHTML' of null"); // error type when element is not defined
	myError instanceof Error // true
	
	
	
	
	function test(){
	
	var v1 = document.getElementById("myid").innerHTML ="zunu"; // to change with this
	
	try {
		  var v1 = document.getElementById("myidd").innerHTML ="zunu"; // exception caught
		  } 
		  
	catch (e) {
		  if (e instanceof Error) {
			console.error(e.name + ': ' + e.message) // error will be displayed at browser console
		  }
  }
  finally{
		var v1 = document.getElementById("myid").innerHTML ="Text Changed to Zunu"; // finally innerHTML changed to this.
	}
	
	}
	
</script>
<p id="myid">This text will change</p>
<input type="button" onclick="test();">
</body>
</html>


0

या विभिन्न प्रकार की त्रुटियों के लिए इसका उपयोग करते हैं

function isError(val) {
  return (!!val && typeof val === 'object')
    && ((Object.prototype.toString.call(val) === '[object Error]')
      || (typeof val.message === 'string' && typeof val.name === 'string'))
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.