জেএসে টাইপফুল ত্রুটির জন্য পরীক্ষা করা হচ্ছে


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
@ কোলেকএমসি সমস্যাযুক্ত হবে না যদি ত্রুটিটি কোনও ফ্রেম বা অন্য উইন্ডোয় কোড থেকে আসতে পারে? সেক্ষেত্রে বিভিন্ন প্রোটোটাইপ ত্রুটিযুক্ত বস্তু থাকবে এবং উদাহরণটি প্রত্যাশার মতো কাজ করবে না। (দেখুন developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... )
Doin থেকে

@ ডিন, আমি এটা মনে করি না। এটি কেবল আসল ত্রুটি বস্তুকে বৈধতা দেবে।
colecmc

1
@ কোলেকাম্যাক, আমি মনে করি আপনি এটি পেয়ে যাবেন যদি আপনি errএকটি আইফ্রেমে ফেলে (বলুন), তবে তা হস্তান্তর করার জন্য এটি প্যারেন্ট উইন্ডোতে পৌঁছে দিলে আপনি পাবেন (err instanceof Error) === false। কারণ ইফ্রেমে এবং এর প্যারেন্ট উইন্ডোটির আলাদা, পৃথক Errorঅবজেক্টের প্রোটোটাইপ রয়েছে। তেমনি উইলের মতো কোনও বস্তু obj = {};যখন আলাদা উইন্ডোতে চলমান কোনও ফাংশনটিতে পৌঁছে দেয়, ততক্ষণ (obj instanceof Object)===false। (এমনকি খারাপ, অর্থাৎ, আপনি যদি obj একটি রেফারেন্স রাখতে পর তার জানালা ধ্বংস হয় বা নেভিগেট, মত কল বস্তুর প্রোটোটাইপ FNS বের করার চেষ্টা 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

ত্রুটিটি যেখানে চেক হচ্ছে তার চেয়ে আলাদা উইন্ডো / ফ্রেম / আইফ্রেমে ফেলে দেওয়া থাকলে কাজ করবে না। সেক্ষেত্রে instanceof Errorচেকটি মিথ্যা, এমনকি কোনও Errorসামগ্রীর জন্যও ফিরে আসবে । সেক্ষেত্রে সবচেয়ে সহজ পদ্ধিতি হ'ল হাঁস-টাইপিং।

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

তবে, আপনার কাছে যদি অ-ত্রুটিযুক্ত উপাদান রয়েছে stackএবং messageবৈশিষ্ট্যগুলি থাকে তবে হাঁস-টাইপিং মিথ্যা ইতিবাচক উত্পাদন করতে পারে ।


1
@ অরলিয়ানআরিবন এটি একটি ReferenceErrorদৃষ্টান্ত দিয়ে ঠিক কাজ করে । আপনি বিশ্বব্যাপী ReferenceErrorবস্তুটি পরীক্ষা করছেন । এটি চেষ্টা করুন: try { foo } catch (e) { console.log(e instanceof Error) }এটি লগ হয় true। আপনি যদি ReferenceErrorকোনও কারণে বিশ্বব্যাপী বস্তুটি পরীক্ষা করার চেষ্টা করছেন তবে আপনি ব্যবহার করতে পারেনError.isPrototypeOf(ReferenceError)
ট্রট

1
@ অরলিয়ানআরিবন (উহ, এছাড়াও, হ্যাঁ, আপনি নিশ্চিত ছিলেন না যে আপনি "এটি একটি রেফারেন্স এরর দিয়ে কাজ করবে না" যা ভুল, বা যদি আপনি কেবল "এটি বিশ্বব্যাপী রেফারেন্সএররের সাথে কাজ করবে না" যা একেবারে সঠিক, যদিও আমি এমন একটি পরিস্থিতি নিয়ে আসছি যেখানে একজন এটি পরীক্ষা করে দেখবে, তবে এটি ব্যবহারের মামলার বৈধতার চেয়ে আমার কল্পনার অভাব সম্পর্কে আরও বলতে পারে)।
ট্রট

হাহা, এই ছেলেগুলির জন্য দুঃখিত, আমি কেবল একটি অদ্ভুত ত্রুটির মধ্যে আবদ্ধ ছিলাম যেখানে আমার সমস্ত ReferenceErrorউদাহরণগুলির উদাহরণ ছিল না Error। এটি vm.runInNewContext()নোডে কল করার কারণে হয়েছিল , যেখানে সমস্ত মানক প্রোটোটাইপগুলি পুনরায় সংজ্ঞায়িত করা হয়। আমার সমস্ত ফলাফল স্ট্যান্ডার্ড বস্তুর উদাহরণ নয়। আমি এটি সম্পর্কে SO এ খুঁজছিলাম, এবং এই থ্রেডে পড়ে গিয়েছিলাম :)
অরেলিন রিবন

1
আপনি চেষ্টা করতে পারেনconst error = (err instanceof Error || err instanceof TypeError) ? err : new Error(err.message ? err.message : err);
আমির আফ্রিদি

আপনি যদি এটি পরীক্ষা করে দেখেন যে এটির instanceofএকটি নির্দিষ্ট ধরণের ত্রুটি আছে কি না?
oldboy

25

আমি মূল প্রশ্নটি জিজ্ঞাসা করেছি - @ ট্রটের উত্তর অবশ্যই সেরা best

তবে জেএস একটি গতিশীল ভাষা হওয়ার সাথে এবং সেখানে প্রচুর জেএস রানটাইম পরিবেশ থাকার কারণে 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
কোনও ইউটিলিটি ফাংশন বা গ্রন্থাগার লেখার সময় আমি এই সংস্করণটিকে পছন্দ করি। এটি ব্যবহারকারীদের একটি নির্দিষ্ট বৈশ্বিক প্রসঙ্গে সীমাবদ্ধ করে না এবং জেএসওএন থেকে ডিসিরিয়ালাইজড ত্রুটিগুলি সঠিকভাবে পরিচালনা করে।
স্নিকেল করুন

ধন্যবাদ, হ্যাঁ, অনেক ক্ষেত্রে এটি যদি কোনও ত্রুটির মতো দেখায় তবে আমরা একটি ত্রুটির মতো আচরণ করতে পারি। কিছু ক্ষেত্রে হাঁসের টাইপিং সম্পূর্ণ গ্রহণযোগ্য, কিছু ক্ষেত্রে এটি মোটেও গ্রহণযোগ্য নয়, এক্ষেত্রে পুরোপুরি ঠিক আছে।
আলেকজান্ডার মিলস

আমি একটি ডিবাগার ব্যবহার করে কিছু ডিবাগিং করেছি, এবং স্ট্যাক এবং বার্তাটি সত্যই ত্রুটির উদাহরণগুলিতে কেবলমাত্র দুটি অ-নেটিভ সম্পত্তি হিসাবে উপস্থিত হয়।
আলেকজান্ডার মিলস

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

আপনি অবজেক্টের "শ্রেণি" পরীক্ষা করতে অবজেক্ট কনট্রাক্টর.নাম ব্যবহার করতে পারেন https://developer.mozilla.org/en-US/docs/Web/JavaScript/ উল্লেখ / গ্লোবাল_অবজেক্টস / ফাংশন / নাম# ফাংশন_নাম_ইন_ ক্লাস

উদাহরণ স্বরূপ

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

উপরের লাইনটি "ত্রুটি" লগ করবে যা বস্তুর শ্রেণীর নাম। এটি জাভাস্ক্রিপ্টের যে কোনও ক্লাসের সাথে ব্যবহার করা যেতে পারে, যদি ক্লাসটি "নামের" নামে যে কোনও সম্পত্তি ব্যবহার না করে থাকে


কোড মিন্ফ করার সময় এবং ত্রুটি
সাবক্ল্যাস

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'))
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.