আমি কীভাবে জাভাস্ক্রিপ্টে একটি কাস্টম ত্রুটি তৈরি করব?


215

কোনও কারণে দেখে মনে হচ্ছে কনস্ট্রাক্টর প্রতিনিধি নিম্নলিখিত স্নিপেটে কাজ করে না:

function NotImplementedError() { 
  Error.apply(this, arguments); 
}
NotImplementedError.prototype = new Error();

var nie = new NotImplementedError("some message");
console.log("The message is: '"+nie.message+"'")

এই চালানো দেয় The message is: ''। কেন, বা যদি একটি নতুন Errorসাবক্লাস তৈরি করার আরও ভাল উপায় আছে তবে কোনও ধারণা ? applyনেটিভ Errorকনস্ট্রাক্টরের সাথে লিখিত সমস্যা আছে যা সম্পর্কে আমি জানি না?


আপনার পরিবর্তনগুলির পরে নোট-ইমপ্লিমেন্টেড এরির দৃser়তা কী কাজ করে? আমি ভেবেছিলাম যে এটি কাজ করার জন্য আপনাকে স্পষ্টরূপে NotImplementedError.prototype.constructor সংজ্ঞা দেওয়া দরকার।
জয়য়ারজো

পরের বার, দয়া করে আপনার সমস্যাটি প্রদর্শনের জন্য প্রয়োজনীয় নয় এমন সমস্ত বহিরাগত কোড ছিঁড়ে ফেলুন। এছাড়াও, ডাব্লিউটিসি কি জেএস.জার? সমস্যা পুনরুত্পাদন করা প্রয়োজন?
বিটি

2
এই প্রশ্নটি সম্পাদনা করা হয়েছে যাতে এটি 10 ​​মিনিটের পরিবর্তে 10 সেকেন্ডের মধ্যে বোঝা যায়
বিটি

আমি একটি উত্তরাধিকার / শ্রেণি পাঠাগার তৈরি করেছি যা ত্রুটি প্রকার থেকে সঠিকভাবে উত্তরাধিকার সূত্রে প্রাপ্ত হয়েছে: github.com/fresheneesz/proto
বিটি

1
শীর্ষ উত্তরের কয়েকটি জন্য jsfiddle
নট

উত্তর:


194

ত্রুটি.প্রোটোটাইপ এবং উদাহরণ হিসাবে আপনার প্রোটোটাইপ বরাদ্দ করতে আপনার কোড আপডেট করুন এবং আপনার দৃser় কাজের জন্য।

function NotImplementedError(message) {
    this.name = "NotImplementedError";
    this.message = (message || "");
}
NotImplementedError.prototype = Error.prototype;

যাইহোক, আমি কেবল আপনার নিজের অবজেক্ট ছুঁড়ে ফেলব এবং কেবল নামের সম্পত্তিটি পরীক্ষা করব।

throw {name : "NotImplementedError", message : "too lazy to implement"}; 

মন্তব্যের ভিত্তিতে সম্পাদনা করুন

মন্তব্যগুলি দেখার পরে এবং মনে করার চেষ্টা করার পরে কেন নিকোলাস জাকাস তার নিবন্ধে যেমন করেছেন তার Error.prototypeপরিবর্তে আমি প্রোটোটাইপ বরাদ্দ করব, আমি নীচের কোড সহ একটি জেএসফিডাল তৈরি করেছি :new Error()

function NotImplementedError(message) {
  this.name = "NotImplementedError";
  this.message = (message || "");
}
NotImplementedError.prototype = Error.prototype;

function NotImplementedError2(message) {
  this.message = (message || "");
}
NotImplementedError2.prototype = new Error();

try {
  var e = new NotImplementedError("NotImplementedError message");
  throw e;
} catch (ex1) {
  console.log(ex1.stack);
  console.log("ex1 instanceof NotImplementedError = " + (ex1 instanceof NotImplementedError));
  console.log("ex1 instanceof Error = " + (ex1 instanceof Error));
  console.log("ex1.name = " + ex1.name);
  console.log("ex1.message = " + ex1.message);
}

try {
  var e = new NotImplementedError2("NotImplementedError2 message");
  throw e;
} catch (ex1) {
  console.log(ex1.stack);
  console.log("ex1 instanceof NotImplementedError2 = " + (ex1 instanceof NotImplementedError2));
  console.log("ex1 instanceof Error = " + (ex1 instanceof Error));
  console.log("ex1.name = " + ex1.name);
  console.log("ex1.message = " + ex1.message);
}

কনসোল আউটপুটটি এটি ছিল।

undefined
ex1 instanceof NotImplementedError = true
ex1 instanceof Error = true
ex1.name = NotImplementedError
ex1.message = NotImplementedError message
Error
    at window.onload (http://fiddle.jshell.net/MwMEJ/show/:29:34)
ex1 instanceof NotImplementedError2 = true
ex1 instanceof Error = true
ex1.name = Error
ex1.message = NotImplementedError2 message

এটি নিশ্চিত করে যে "সমস্যা" যার মধ্যে আমি দৌড়েছিলাম তা ছিল ত্রুটির স্ট্যাক সম্পত্তি যেখানে লাইন নম্বর ছিল new Error() তৈরি হয়েছিল এবং কোথায় throw eঘটেছিল তা নয় । তবে এটির চেয়ে ভাল হতে পারে যে NotImplementedError.prototype.name = "NotImplementedError"ত্রুটিযুক্ত বস্তুকে প্রভাবিত করে এমন কোনও লাইনের পার্শ্ব প্রতিক্রিয়া ।

এছাড়াও, এর সাথে লক্ষ্য করুন NotImplementedError2, যখন আমি .nameস্পষ্টভাবে সেট না করি , এটি "ত্রুটি" এর সমান। যাইহোক, মন্তব্যে উল্লিখিত হিসাবে, কারণ যে সংস্করণটি প্রোটোটাইপ new Error()সেট করে তাই আমি সেট করতে পারি NotImplementedError2.prototype.name = "NotImplementedError2"এবং ঠিক আছি।


45
সেরা উত্তর, তবে Error.prototypeসরাসরি নেওয়া সম্ভবত খারাপ ফর্ম। আপনি যদি পরে NotImplementedError.prototype.toStringকোনও অবজেক্ট যুক্ত করতে চান তবে এর জন্য নতুন নাম রাখুন Error.prototype.toString- আরও ভাল NotImplementedError.prototype = new Error()
cdleary

4
আমি এখনও এই সমস্ত প্রোটোটাইপ জিনিসগুলিতে কিছুটা হারিয়েছি। আপনার উদাহরণে কেন আপনি এই.নামটির নাম অর্পণ করেন এবং নোটিপ্লিমিটেড এরিয়ার.প্রোটোটাইপ.নামকে না? আপনি দয়া করে উত্তর দিতে পারেন, এটা আমার বোঝার জন্য অত্যন্ত গুরুত্বপূর্ণ :)
jayarjo

27
কোড. google.com/p/chromium/issues/detail?id=228909 অনুসারে subclass.prototype = new Error()খারাপ ফর্ম। subclass.prototype = Object.create(superclass.prototype)পরিবর্তে আপনার ব্যবহার করার কথা। আমি আশা করছি এটি স্ট্যাক-ট্রেস সমস্যাটিও ঠিক করতে পারে।
গিলি

8
অর্থবহ স্ট্যাকট্রেস পাওয়ার সহজ কৌশলটি হল কনস্ট্রাক্টরে ত্রুটি উত্পন্ন করা এবং এটির স্ট্যাক সংরক্ষণ করা। এটা সঠিক কল স্ট্যাক +1 কন্সট্রাকটর জন্য লাইন দিতে হবে (এটা উপযুক্ত পে-বন্ধ):this.stack = new Error().stack;
Meredian

6
-1; এটা ভুল. এরকম NotImplementedError.prototype = Error.prototype;দেখা যায় না instanceofআচরণ NotImplementedErrorহিসেবে উপশ্রেণী এর Error, এটা তোলে instanceofসঠিক একই শ্রেণী হিসেবে আচরণ তাদের। যদি আপনি উপরের কোডটি আপনার কনসোলে পেস্ট করেন এবং চেষ্টা করেন তবে new Error() instanceof NotImplementedErrorআপনি পাবেন trueযা স্পষ্টতই ভুল।
মার্ক আমেরিকা

87

উপরোক্ত সমস্ত উত্তর ভয়াবহ - সত্যই। এমনকি একটি 107 আপ সঙ্গে! আসল উত্তর এখানে ছেলেরা:

ত্রুটি বস্তু থেকে উত্তরাধিকারী - বার্তা সম্পত্তি কোথায়?

টি এল; ডিআর:

উ: কারণটি messageসেট না হওয়ার কারণ হ'ল এটি Errorএমন একটি ফাংশন যা একটি নতুন ত্রুটিযুক্ত বস্তুটি ফেরত দেয় এবং ম্যানিপুলেট করে নাthis কোন ভাবেই।

বি। এই কাজটি করার উপায়টি হ'ল কন্সট্রাক্টরের কাছ থেকে প্রয়োগের ফলাফলটি ফেরত দেওয়া, পাশাপাশি সাধারণ জটিল জাভাস্ক্রিপি পদ্ধতিতে প্রোটোটাইপ সেট করা:

function MyError() {
    var temp = Error.apply(this, arguments);
    temp.name = this.name = 'MyError';
    this.message = temp.message;
    if(Object.defineProperty) {
        // getter for more optimizy goodness
        /*this.stack = */Object.defineProperty(this, 'stack', { 
            get: function() {
                return temp.stack
            },
            configurable: true // so you can change it if you want
        })
    } else {
        this.stack = temp.stack
    }
}
//inherit prototype using ECMAScript 5 (IE 9+)
MyError.prototype = Object.create(Error.prototype, {
    constructor: {
        value: MyError,
        writable: true,
        configurable: true
    }
});

var myError = new MyError("message");
console.log("The message is: '" + myError.message + "'"); // The message is: 'message'
console.log(myError instanceof Error); // true
console.log(myError instanceof MyError); // true
console.log(myError.toString()); // MyError: message
console.log(myError.stack); // MyError: message \n 
// <stack trace ...>


 
//for EMCAScript 4 or ealier (IE 8 or ealier), inherit prototype this way instead of above code:
/*
var IntermediateInheritor = function() {};
IntermediateInheritor.prototype = Error.prototype;
MyError.prototype = new IntermediateInheritor();
*/

আপনি সম্ভবত গনা কিছু কপট সমস্ত অ-গণনীয় বৈশিষ্ট্য মাধ্যমে কাজ করতে পারে tmpত্রুটি তাদের সেট করার বরং স্পষ্টভাবে শুধুমাত্র সেটিং চেয়ে stackএবং messageকিন্তু কপট অর্থাত সমর্থিত নয় <9


2
এই সমাধানটি একটি বিদ্যমান ত্রুটি সহ একটি কাস্টম ত্রুটি ইনস্ট্যান্ট করার জন্যও কাজ করে। আপনি যদি কোনও তৃতীয় পক্ষের লাইব্রেরি ব্যবহার করছেন এবং আপনার নিজস্ব কাস্টম প্রকারের সাথে একটি বিদ্যমান ত্রুটি মোড়ানো করতে চান তবে অন্যান্য পদ্ধতিগুলি সঠিকভাবে কাজ করে না। এফওয়াইআই, আপনি ভ্যানিলা ত্রুটিগুলিকে একটি বিদ্যমান ত্রুটি পেরিয়ে ইনস্ট্যান্ট করতে পারেন।
কাইল

1
আপনার return thisকোনও কনস্ট্রাক্টরে থাকা উচিত নয় ।
ওনুর ইল্ডারিয়াম

13
আমি এই পদ্ধতিটি কিছুটা সরল ও উন্নত করেছি: jsbin.com/rolojuhuya/1/edit?js,console
ম্যাট

3
@ ম্যাটক্যান্টর সম্ভবত এটির উত্তর দেবেন? আমার মনে হয় আমি তোমার সেরা পছন্দ করি
এমপিআইসট

2
পরিবর্তে temp.name = this.name = 'MyError', আপনি করতে পারেন temp.name = this.name = this.constructor.name। সেভাবে এটি সাবক্লাসগুলির জন্যও কাজ করবে MyError
জো লিস

45

ES2015 এ, আপনি classএটি পরিষ্কারভাবে এটি করতে ব্যবহার করতে পারেন :

class NotImplemented extends Error {
  constructor(message = "", ...args) {
    super(message, ...args);
    this.message = message + " has not yet been implemented.";
  }
}

এটি গ্লোবাল Errorপ্রোটোটাইপ পরিবর্তন করে না , আপনাকে কাস্টমাইজ করতে দেয় message,name এবং অন্যান্য বৈশিষ্ট্য, এবং সঠিকভাবে স্ট্যাক ধারন করে না। এটিও বেশ পঠনযোগ্য।

অবশ্যই, আপনার একটি সরঞ্জাম ব্যবহার করার প্রয়োজন হতে পারে babelযদি আপনার কোডটি পুরানো ব্রাউজারগুলিতে চলমান থাকে।


23

যদি কোনও কাস্টম ত্রুটি তৈরি করতে এবং স্ট্যাকের ট্রেস কীভাবে পাওয়া যায় সে সম্পর্কে যদি কেউ আগ্রহী হন :

function CustomError(message) {
  this.name = 'CustomError';
  this.message = message || '';
  var error = new Error(this.message);
  error.name = this.name;
  this.stack = error.stack;
}
CustomError.prototype = Object.create(Error.prototype);

try {
  throw new CustomError('foobar');
}
catch (e) {
  console.log('name:', e.name);
  console.log('message:', e.message);
  console.log('stack:', e.stack);
}

7

স্ট্যান্ডার্ডের এই বিভাগটি ব্যাখ্যা করতে পারে কেন Error.applyকলটি কেন বস্তুটি আরম্ভ করে না:

15.11.1 ত্রুটি নির্মাণকারীকে একটি ফাংশন হিসাবে ডাকা হয়

যখন ত্রুটিটিকে কনস্ট্রাক্টর না করে ফাংশন হিসাবে ডাকা হয়, এটি একটি নতুন ত্রুটিযুক্ত বস্তু তৈরি করে এবং আরম্ভ করে। সুতরাং ফাংশন কল ত্রুটি (...) একই যুক্তি সহ নতুন ত্রুটি (...) অবজেক্ট তৈরির এক্সপ্রেশনের সমতুল্য।

এই ক্ষেত্রে Errorফাংশনটি সম্ভবত নির্ধারণ করে যে এটি নির্মাণকারী হিসাবে ডাকা হচ্ছে না, সুতরাং এটি thisঅবজেক্টটি আরম্ভ করার পরিবর্তে একটি নতুন ত্রুটি উদাহরণ দেয় ।

নিম্নলিখিত কোডের সাথে পরীক্ষার মাধ্যমে বোঝা যাচ্ছে যে বাস্তবে এটি ঘটছে:

function NotImplementedError() { 
   var returned = Error.apply(this, arguments);
   console.log("returned.message = '" + returned.message + "'");
   console.log("this.message = '" + this.message + "'");
}
NotImplementedError.prototype = new Error();

var nie = new NotImplementedError("some message");

এটি চালিত হলে নিম্নলিখিত আউটপুট উত্পন্ন হয়:

returned.message = 'some message'
this.message = ''

এটি কীভাবে কাস্টম ত্রুটি শ্রেণির সাথে সিমুলেটেড করা যায়? উদাহরণস্বরূপ, কীভাবে আমার কাস্টম ত্রুটি শ্রেণি একটি ফাংশন হিসাবে উদাহরণ তৈরি করে এবং নির্মাণকারী হিসাবে ব্যবহার করা যেতে পারে?
লেয়া হেইস

না, এটা সত্য নয়। যদি এটি কোনও নতুন ত্রুটির উদাহরণ ফেরত দেয়, তবে তার সংস্থান সম্পত্তিটি কাজ করবে।
বিটি

@BT কিভাবে নতুন উদাহরণ উপর বার্তা সম্পত্তি বার্তা সম্পত্তি প্রভাব ফেলে thisমধ্যে Error.apply(this, arguments);? আমি বলছি এখানে ত্রুটিতে কলটি একটি নতুন অবজেক্ট তৈরি করছে, যা ফেলে দেওয়া হয়েছে; ইতিমধ্যে নির্ধারিত অবজেক্টটি আরম্ভ করা হচ্ছে না যা বরাদ্দ করা হয়েছে nie
ডেভ

@ বিটি আমি এমন কয়েকটি উদাহরণ কোড যুক্ত করেছি যা আমি কী বলতে চাইছিলাম তা আশাবাদী পরিষ্কার হয়ে যায়।
ডেভ

@ ডেভ আমি এখানে উদ্দেশ্য ভুল বুঝতে পারি, কিন্তু আপনার NotImplementedErrorবাস্তবায়ন returnedপরিবর্তনশীল ফিরে না উচিত ?
ব্লু

7
function InvalidValueError(value, type) {
    this.message = "Expected `" + type.name + "`: " + value;
    var error = new Error(this.message);
    this.stack = error.stack;
}
InvalidValueError.prototype = new Error();
InvalidValueError.prototype.name = InvalidValueError.name;
InvalidValueError.prototype.constructor = InvalidValueError;

3
এটি এখানে সেরা উত্তর। এটি সাফল্য এবং এইভাবে তৈরি ব্যতিক্রমটি সমস্ত পরিস্থিতিতে সঠিকভাবে আচরণ করবে। এটি স্ট্যাক ট্রেস সংরক্ষণ করে যা নন তুচ্ছ অ্যাপ্লিকেশনগুলিতে খুব গুরুত্বপূর্ণ। আমি কেবল "প্রোটোটাইপ = নতুন ত্রুটি ()" এর সাথে "প্রোটোটাইপ = অবজেক্ট.ক্রিয়েট (ত্রুটি.প্রোটোটাইপ)" প্রতিস্থাপন করব। Node.js জন্যে রয়েছে ছোট গ্রন্থাগার যে জন্য আপনি এই আছে হল: npmjs.com/package/node-custom-errors
Lukasz Korzybski

6

আমি এই একই সমস্যা ছিল। আমার ত্রুটি চাহিদা একটি হতে instanceofউভয় Errorএবং NotImplemented, এবং এটা কনসোলে একটি সুসঙ্গত ব্যাক-ট্রেস উত্পাদন করতে হবে।

আমার সমাধান:

var NotImplemented = (function() {
  var NotImplemented, err;
  NotImplemented = (function() {
    function NotImplemented(message) {
      var err;
      err = new Error(message);
      err.name = "NotImplemented";
      this.message = err.message;
      if (err.stack) this.stack = err.stack;
    }
    return NotImplemented;
  })();
  err = new Error();
  err.name = "NotImplemented";
  NotImplemented.prototype = err;

  return NotImplemented;
}).call(this);

// TEST:
console.log("instanceof Error: " + (new NotImplemented() instanceof Error));
console.log("instanceof NotImplemented: " + (new NotImplemented() instanceofNotImplemented));
console.log("message: "+(new NotImplemented('I was too busy').message));
throw new NotImplemented("just didn't feel like it");

নোড.জেএস দিয়ে চলার ফলাফল:

instanceof Error: true
instanceof NotImplemented: true
message: I was too busy

/private/tmp/t.js:24
throw new NotImplemented("just didn't feel like it");
      ^
NotImplemented: just didn't feel like it
    at Error.NotImplemented (/Users/colin/projects/gems/jax/t.js:6:13)
    at Object.<anonymous> (/Users/colin/projects/gems/jax/t.js:24:7)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:487:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)

ত্রুটিটি আমার মাপদণ্ডের সমস্ত 3 টি পেরিয়ে যায়, এবং stackসম্পত্তিটি মানহীন হলেও , এটি বেশিরভাগ নতুন ব্রাউজারগুলিতে সমর্থিত যা আমার ক্ষেত্রে গ্রহণযোগ্য।


5

জয়য়েন্টের সাথে কথা বলে আপনি স্ট্যাক সম্পত্তি (যা আমি এখানে প্রচুর উত্তরে দেখছি) নিয়ে গণ্ডগোল করবেন না, কারণ এটির কার্য সম্পাদনে নেতিবাচক প্রভাব পড়বে। তারা যা বলে তা এখানে:

স্ট্যাক: সাধারণত, এটি নিয়ে গণ্ডগোল করবেন না। এমনকি এটি বৃদ্ধি না। V8 কেবল তখনই এটির সংখ্যায়ন করে যদি কেউ প্রকৃতপক্ষে সম্পত্তিটি পড়ে থাকে যা হ্যান্ডেলযোগ্য ত্রুটির জন্য নাটকীয়ভাবে পারফরম্যান্স উন্নত করে। আপনি যদি সম্পত্তিটি কেবল এটি বাড়ানোর জন্য পড়ে থাকেন তবে আপনার কলারের স্ট্যাকের প্রয়োজন না হলেও এমনকি আপনি মূল্য প্রদান করবেন।

আমি মূল ত্রুটি মোড়ানো সম্পর্কে তাদের ধারণাটি উল্লেখ করতে চাই এবং চাই যা স্ট্যাকের উপর দিয়ে যাওয়ার জন্য একটি দুর্দান্ত প্রতিস্থাপন।

সুতরাং আমি এখানে উপরে উল্লিখিত বিবেচনা করে একটি কাস্টম ত্রুটি তৈরি করব:

এস 5 সংস্করণ:

function RError(options) {
    options = options || {}; // eslint-disable-line no-param-reassign
    this.name = options.name;
    this.message = options.message;
    this.cause = options.cause;

    // capture stack (this property is supposed to be treated as private)
    this._err = new Error();

    // create an iterable chain
    this.chain = this.cause ? [this].concat(this.cause.chain) : [this];
}
RError.prototype = Object.create(Error.prototype, {
    constructor: {
        value: RError,
        writable: true,
        configurable: true
    }
});

Object.defineProperty(RError.prototype, 'stack', {
    get: function stack() {
        return this.name + ': ' + this.message + '\n' + this._err.stack.split('\n').slice(2).join('\n');
    }
});

Object.defineProperty(RError.prototype, 'why', {
    get: function why() {
        var _why = this.name + ': ' + this.message;
        for (var i = 1; i < this.chain.length; i++) {
            var e = this.chain[i];
            _why += ' <- ' + e.name + ': ' + e.message;
        }
        return _why;
    }
});

// usage

function fail() {
    throw new RError({
        name: 'BAR',
        message: 'I messed up.'
    });
}

function failFurther() {
    try {
        fail();
    } catch (err) {
        throw new RError({
            name: 'FOO',
            message: 'Something went wrong.',
            cause: err
        });
    }
}

try {
    failFurther();
} catch (err) {
    console.error(err.why);
    console.error(err.stack);
    console.error(err.cause.stack);
}

এস 6 সংস্করণ:

class RError extends Error {
    constructor({name, message, cause}) {
        super();
        this.name = name;
        this.message = message;
        this.cause = cause;
    }
    [Symbol.iterator]() {
        let current = this;
        let done = false;
        const iterator = {
            next() {
                const val = current;
                if (done) {
                    return { value: val, done: true };
                }
                current = current.cause;
                if (!val.cause) {
                    done = true;
                }
                return { value: val, done: false };
            }
        };
        return iterator;
    }
    get why() {
        let _why = '';
        for (const e of this) {
            _why += `${_why.length ? ' <- ' : ''}${e.name}: ${e.message}`;
        }
        return _why;
    }
}

// usage

function fail() {
    throw new RError({
        name: 'BAR',
        message: 'I messed up.'
    });
}

function failFurther() {
    try {
        fail();
    } catch (err) {
        throw new RError({
            name: 'FOO',
            message: 'Something went wrong.',
            cause: err
        });
    }
}

try {
    failFurther();
} catch (err) {
    console.error(err.why);
    console.error(err.stack);
    console.error(err.cause.stack);
}

আমি আমার সমাধানটি একটি মডিউলে রেখেছি, এটি এখানে: https://www.npmjs.com/package/rerror


3

আমি এটি এর মতো করতে পছন্দ করি:

  • নাম ব্যবহার করুন যাতে স্ট্রিং () ছোঁড়ে"{code}: {message}"
  • একই জিনিসকে সুপারের দিকে ফিরিয়ে দিন যাতে এটি স্ট্যাকট্রেসে একই দেখা যায়
  • কোড সংযুক্ত করুন error.code চেকিং / পার্সিং হিসাবে কোনও বার্তা যাচাই করার চেয়ে কোডে কোডের পার্সিং করা ভাল, যা আপনি উদাহরণ হিসাবে স্থানীয়করণ করতে চাইতে পারেন
  • error.messageবিকল্প হিসাবে বার্তা সংযুক্ত করুনerror.toString()

class AppException extends Error {
  constructor(code, message) {
    const fullMsg = message ? `${code}: ${message}` : code;
    super(fullMsg);
    this.name = code;
    this.code = code;
    this.message = fullMsg;
  }
  
  toString() {
    return this.message;
  }
}

// Just a code
try {
  throw new AppException('FORBIDDEN');
} catch(e) {
  console.error(e);
  console.error(e.toString());
  console.log(e.code === 'FORBIDDEN');
}

// A code and a message
try {
  throw new AppException('FORBIDDEN', 'You don\'t have access to this page');
} catch(e) {
  console.error(e);
  console.error(e.toString());
  console.log(e.code === 'FORBIDDEN');
}


2

আমি ঠিক এর মতো কিছু বাস্তবায়ন করতে পেরেছিলাম এবং খুঁজে পেয়েছি যে স্ট্যাকটি আমার নিজের ত্রুটি বাস্তবায়নে হারিয়ে গেছে। আমার যা করতে হবে তা ছিল একটি ছদ্মবেশী ত্রুটি তৈরি করা এবং এটি থেকে স্ট্যাকটি পুনরুদ্ধার করা:

My.Error = function (message, innerException) {
    var err = new Error();
    this.stack = err.stack; // IMPORTANT!
    this.name = "Error";
    this.message = message;
    this.innerException = innerException;
}
My.Error.prototype = new Error();
My.Error.prototype.constructor = My.Error;
My.Error.prototype.toString = function (includeStackTrace) {
    var msg = this.message;
    var e = this.innerException;
    while (e) {
        msg += " The details are:\n" + e.message;
        e = e.innerException;
    }
    if (includeStackTrace) {
        msg += "\n\nStack Trace:\n\n" + this.stack;
    }
    return msg;
}

এটি বার্তাটি সেট করে না
বিটি

2

আমি নতুন ত্রুটিযুক্ত বস্তু তৈরি করতে কনস্ট্রাক্টর প্যাটার্নটি ব্যবহার করেছি। আমি উদাহরণ হিসাবে প্রোটোটাইপ চেইন সংজ্ঞায়িত করেছি Error। MDN ত্রুটি নির্মাণকারী উল্লেখ দেখুন।

আপনি এই উপর এই স্নিপেট পরীক্ষা করতে পারবেন সারকথা

বাস্তবায়ন

// Creates user-defined exceptions
var CustomError = (function() {
  'use strict';

  //constructor
  function CustomError() {
    //enforces 'new' instance
    if (!(this instanceof CustomError)) {
      return new CustomError(arguments);
    }
    var error,
      //handles the arguments object when is passed by enforcing a 'new' instance
      args = Array.apply(null, typeof arguments[0] === 'object' ? arguments[0] : arguments),
      message = args.shift() || 'An exception has occurred';

    //builds the message with multiple arguments
    if (~message.indexOf('}')) {
      args.forEach(function(arg, i) {
        message = message.replace(RegExp('\\{' + i + '}', 'g'), arg);
      });
    }

    //gets the exception stack
    error = new Error(message);
    //access to CustomError.prototype.name
    error.name = this.name;

    //set the properties of the instance
    //in order to resemble an Error instance
    Object.defineProperties(this, {
      stack: {
        enumerable: false,
        get: function() { return error.stack; }
      },
      message: {
        enumerable: false,
        value: message
      }
    });
  }

  // Creates the prototype and prevents the direct reference to Error.prototype;
  // Not used new Error() here because an exception would be raised here,
  // but we need to raise the exception when CustomError instance is created.
  CustomError.prototype = Object.create(Error.prototype, {
    //fixes the link to the constructor (ES5)
    constructor: setDescriptor(CustomError),
    name: setDescriptor('JSU Error')
  });

  function setDescriptor(value) {
    return {
      configurable: false,
      enumerable: false,
      writable: false,
      value: value
    };
  }

  //returns the constructor
  return CustomError;
}());

, USAGE

কাস্টমআরার কনস্ট্রাক্টর বার্তাটি তৈরি করতে অনেকগুলি আর্গুমেন্ট গ্রহণ করতে পারে, যেমন

var err1 = new CustomError("The url of file is required"),
    err2 = new CustomError("Invalid Date: {0}", +"date"),
    err3 = new CustomError("The length must be greater than {0}", 4),
    err4 = new CustomError("Properties .{0} and .{1} don't exist", "p1", "p2");

throw err4;

এবং কাস্টম ত্রুটিটি এইভাবে দেখায়:

কাস্টম ত্রুটি প্রোটোটাইপ চেইন


যিনি হ্রাস করেছেন, আপনার কি তর্ক আছে, বা ভোট দেওয়ার কোনও কারণ আছে? বা কোডটিতে উদ্দেশ্যটি বুঝতে পারে না।
ঝেরেক্স

আমি কেবল লক্ষ্য করেছি যে এই পৃষ্ঠাটি ব্রাউজ করার সময় আমি অবশ্যই দুর্ঘটনাক্রমে ডাউনভোট বোতামটি ক্লিক করে বুঝতে পেরেছি (সম্ভবত আমার ফোন থেকে ব্রাউজ করছে)। আমার ইতিহাসটি ব্রাউজ করার সময় আমি কেবল আজ লক্ষ্য করেছি। এটি অবশ্যই উদ্দেশ্যমূলক ছিল না তবে আমি এটিকে পূর্বাবস্থায় ফেলাতে পারছি না কারণ এটি গ্রেস পিরিয়ডের পরে over আপনি একটি তথ্যমূলক উত্তর সরবরাহ করেছেন এবং অবশ্যই এটি প্রাপ্য নয়। আপনি যদি কোনও সম্পাদনা করেন তবে আমি আনন্দের সাথে ডাউনভোটটি পূর্বাবস্থায় ফিরিয়ে আনব। এর জন্যে দুঃখিত.
jschr

1

কনস্ট্রাক্টরটির একটি কারখানা পদ্ধতির মতো হওয়া উচিত এবং আপনি যা চান তা ফিরিয়ে দিন। আপনার যদি অতিরিক্ত পদ্ধতি / বৈশিষ্ট্য প্রয়োজন হয় তবে এটিকে ফেরত দেওয়ার আগে আপনি এগুলিতে যুক্ত করতে পারেন।

function NotImplementedError(message) { return new Error("Not implemented", message); }

x = new NotImplementedError();

যদিও আমি নিশ্চিত নই কেন আপনার এটি করা দরকার। শুধু ব্যবহার new Error...করবেন না কেন ? কাস্টম ব্যতিক্রমগুলি সত্যিই জাভাস্ক্রিপ্টে খুব বেশি যোগ করে না (বা সম্ভবত কোনও টাইপযুক্ত ভাষা)।


2
আপনাকে জাভাস্ক্রিপ্টে ত্রুটি-টাইপ-স্তরক্রম বা অবজেক্ট-মানটি স্যুইচ করতে হবে কারণ আপনি কেবলমাত্র একটি সিঙ্গল ব্লক নির্দিষ্ট করতে পারেন specify আপনার সমাধানে, (x উদাহরণস্বরূপ NotImplementedError) মিথ্যা, যা আমার ক্ষেত্রে গ্রহণযোগ্য নয়।
সিডিলারি

1

এটি সিসিয়াম বিকাশকারীতে দুর্দান্তভাবে প্রয়োগ করা হয়েছে:

এটি সরল রূপে:

var NotImplementedError = function(message) {
    this.name = 'NotImplementedError';
    this.message = message;
    this.stack = (new Error()).stack;
}

// Later on...

throw new NotImplementedError();

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

এছাড়াও, error instanceof Errorপরীক্ষায় উত্তীর্ণ হয় না , যা সহায়ক হতে পারে।
লরেন

1

এটি আমার বাস্তবায়ন:

class HttpError extends Error {
  constructor(message, code = null, status = null, stack = null, name = null) {
    super();
    this.message = message;
    this.status = 500;

    this.name = name || this.constructor.name;
    this.code = code || `E_${this.name.toUpperCase()}`;
    this.stack = stack || null;
  }

  static fromObject(error) {
    if (error instanceof HttpError) {
      return error;
    }
    else {
      const { message, code, status, stack } = error;
      return new ServerError(message, code, status, stack, error.constructor.name);
    }
  }

  expose() {
    if (this instanceof ClientError) {
      return { ...this };
    }
    else {
      return {
        name: this.name,
        code: this.code,
        status: this.status,
      }
    }
  }
}

class ServerError extends HttpError {}

class ClientError extends HttpError { }

class IncorrectCredentials extends ClientError {
  constructor(...args) {
    super(...args);
    this.status = 400;
  }
}

class ResourceNotFound extends ClientError {
  constructor(...args) {
    super(...args);
    this.status = 404;
  }
}

ব্যবহার # 1 উদাহরণ:

app.use((req, res, next) => {
  try {
    invalidFunction();
  }
  catch (err) {
    const error = HttpError.fromObject(err);
    return res.status(error.status).send(error.expose());
  }
});

ব্যবহার # 2 উদাহরণ:

router.post('/api/auth', async (req, res) => {
  try {
    const isLogged = await User.logIn(req.body.username, req.body.password);

    if (!isLogged) {
      throw new IncorrectCredentials('Incorrect username or password');
    }
    else {
      return res.status(200).send({
        token,
      });
    }
  }
  catch (err) {
    const error = HttpError.fromObject(err);
    return res.status(error.status).send(error.expose());
  }
});

0

ব্যবহার করতে সক্ষম না হওয়ার ব্যয়ে instanceof, নিম্নলিখিতটি মূল স্ট্যাক ট্রেস সংরক্ষণ করে এবং কোনও মানহীন কৌশল ব্যবহার করে না।

// the function itself
var fixError = function(err, name) {
    err.name = name;
    return err;
}

// using the function
try {
    throw fixError(new Error('custom error message'), 'CustomError');
} catch (e) {
    if (e.name == 'CustomError')
        console.log('Wee! Custom Error! Msg:', e.message);
    else
        throw e; // unhandled. let it propagate upwards the call stack
}

উদাহরণস্বরূপ আপনি এখানে যা করতে চান তা হ'ল কেবলমাত্র ফিক্সররের পরিবর্তে নতুন ফিক্স এরর ফেলে দিন
বিটি

@ বিটি: fixErrorউপরের ফাংশনটির সাথে নয় । newকল করার সময় একটি যুক্ত করা কেবল এমন একটি বস্তু তৈরি করবে যা ফেলে দেওয়া হবে।
টিজে ক্রাউডার

ওহ আমি "fixError instanceof" ব্যবহার অভিপ্রেত - কোর্স তারপর এর "ত্রুটি instanceof" কাজ না .. আমি অনুমান যে খারাপ ..
বিটি

0

অন্য বিকল্প, সমস্ত পরিবেশে কাজ নাও করতে পারে Aআলাস্টাস্ট আশ্বাস দিয়েছে এটি নোডেজ 0.8 এ কাজ করে This

function myError(msg){ 
      var e = new Error(msg); 
      _this = this; 
      _this.__proto__.__proto__ = e;
}

0

আপনি যদি নোড / ক্রোম ব্যবহার করছেন। নিম্নলিখিত স্নিপেটটি আপনাকে এক্সটেনশান দেয় যা নিম্নলিখিত প্রয়োজনীয়তাগুলি পূরণ করে।

  • err instanceof Error
  • err instanceof CustomErrorType
  • কনসোল.লগ () প্রদান করে [CustomErrorType] বার্তা দিয়ে তৈরি করার পরে
  • [CustomErrorType: message]কোনও বার্তা ছাড়াই তৈরি করা হলে কনসোল.লগ () ফিরে আসে
  • নিক্ষেপ / স্ট্যাক ত্রুটিটি তৈরি হওয়ার সময় তথ্য সরবরাহ করে।
  • নোড.জেএস এবং Chrome এ অনুকূলভাবে কাজ করে।
  • ক্রোম, সাফারি, ফায়ারফক্স এবং আই 8+ এর উদাহরণগুলি পরীক্ষাগুলি পাস করবে তবে ক্রোম / সাফারির বাইরে কোনও বৈধ স্ট্যাক থাকবে না। আমি এটির সাথে ঠিক আছি কারণ আমি ক্রোমে ডিবাগ করতে পারি তবে নির্দিষ্ট কোডের জন্য প্রয়োজনীয় কোডটি এখনও ক্রস ব্রাউজারে কাজ করবে। আপনার যদি কেবল নোডের প্রয়োজন হয় তবে আপনি সহজেই ifবিবৃতিগুলি সরিয়ে ফেলতে পারেন এবং আপনি ভাল

টুকিটাকি

var CustomErrorType = function(message) {
    if (Object.defineProperty) {
        Object.defineProperty(this, "message", {
            value : message || "",
            enumerable : false
        });
    } else {
        this.message = message;
    }

    if (Error.captureStackTrace) {
        Error.captureStackTrace(this, CustomErrorType);
    }
}

CustomErrorType.prototype = new Error();
CustomErrorType.prototype.name = "CustomErrorType";

ব্যবহার

var err = new CustomErrorType("foo");

আউটপুট

var err = new CustomErrorType("foo");
console.log(err);
console.log(err.stack);

[CustomErrorType: foo]
CustomErrorType: foo
    at Object.<anonymous> (/errorTest.js:27:12)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:906:3

/errorTest.js:30
        throw err;
              ^
CustomErrorType: foo
    at Object.<anonymous> (/errorTest.js:27:12)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:906:3

0

নিম্নলিখিতটি আমার জন্য অফিসিয়াল মোজিলা ডকুমেন্টেশন ত্রুটি থেকে নেওয়া কাজ করেছে ।

function NotImplementedError(message) {
    var instance = new Error(message);
    instance.name = 'NotImplementedError';

    Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
    if (Error.captureStackTrace) {
        Error.captureStackTrace(instance, NotImplementedError);
    }
    return instance;
}

NotImplementedError.prototype = Object.create(Error.prototype, {
    constructor: {
        value: Error,
        enumerable: false,
        writable: true,
        configurable: true
    }
});

-1

ব্যবহারকারীর সংজ্ঞায়িত ত্রুটি ধরণের প্রতিটি উদাহরণের জন্য একটি নতুন প্রোটোটাইপ অবজেক্ট চেষ্টা করুন। এটি instanceofচেকগুলিকে ফায়ারফক্স এবং ভি 8 (কোম, নোডেজ)-তে যথাযথভাবে প্লাস প্রকার এবং বার্তাটি সঠিকভাবে প্রতিবেদন করার আচরণ করতে দেয় ।

function NotImplementedError(message){
    if(NotImplementedError.innercall===undefined){
        NotImplementedError.innercall = true;
        NotImplementedError.prototype = new Error(message);
        NotImplementedError.prototype.name = "NotImplementedError";
        NotImplementedError.prototype.constructor = NotImplementedError;

        return new NotImplementedError(message);
    }
    delete NotImplementedError.innercall;
}

নোট করুন যে একটি অতিরিক্ত এন্ট্রি অন্যথায় সঠিক স্ট্যাকের আগে চলে যাবে।


কাজ করে না। চেষ্টা করুন: var a = new NotImplementedError('a'), b = new NotImplementedError('b');। এখন a instanceof NotImplementedError == falseএবংb instanceof NotImplementedError == true
jjrv

-1

এটি করার দ্রুততম উপায়:

    let thisVar = false

    if (thisVar === false) {
            throw new Error("thisVar is false. It should be true.")
    }

-3

সহজ উপায়। আপনি নিজের বস্তুকে ত্রুটিযুক্ত বস্তু থেকে উত্তরাধিকারী করে তুলতে পারেন। উদাহরণ:

function NotImplementError(message)
{
    this.message = message;
    Error.call();
    Error.call(message);
} 

আমরা যা করছি তা ফাংশন কল () যা ত্রুটি শ্রেণীর নির্মাতাকে কল করে তা মূলত একই জিনিসটি অন্য অবজেক্ট ওরিয়েন্টেড ভাষায় শ্রেণীর উত্তরাধিকার প্রয়োগের মতো।


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