জাভাস্ক্রিপ্টে ত্রুটি বাড়ানোর ভাল উপায় কী?


367

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

পাইথন, সাধারণত, এক ব্যতিক্রম সাবক্লাস হবে।

জেএসে উপযুক্ত জিনিসটি কী?

উত্তর:


217

শুধুমাত্র মানক ক্ষেত্রের ত্রুটিযুক্ত বস্তুটি messageসম্পত্তি the ( এমডিএন , বা একমাস্ক্রিপ্ট ভাষার স্পেসিফিকেশন, বিভাগ 15.11 দেখুন) বাকি সমস্ত কিছুই প্ল্যাটফর্ম নির্দিষ্ট।

Mosts পরিবেশের সেট stackসম্পত্তি, কিন্তু fileNameএবং lineNumberকার্যত উত্তরাধিকার ব্যবহৃত হবে বেহুদা হয়।

সুতরাং, সর্বনিম্ন পদ্ধতিটি হল:

function MyError(message) {
    this.name = 'MyError';
    this.message = message;
    this.stack = (new Error()).stack;
}
MyError.prototype = new Error;  // <-- remove this if you do not 
                                //     want MyError to be instanceof Error

আপনি স্ট্যাকটি স্নিগ্ধ করতে পারেন, এটি থেকে অবাঞ্ছিত উপাদানগুলি আনশিফ্ট করতে পারেন এবং ফাইলনাম এবং লাইন নাম্বারের মতো তথ্য বের করতে পারেন, তবে এটি করার জন্য জাভাস্ক্রিপ্ট প্ল্যাটফর্মের প্ল্যাটফর্ম সম্পর্কে তথ্য প্রয়োজন। বেশিরভাগ ক্ষেত্রে অপ্রয়োজনীয় - এবং আপনি যদি সত্যিই চান তবে আপনি এটি পোস্ট-মর্টেমে করতে পারেন।

সাফারি একটি উল্লেখযোগ্য ব্যতিক্রম। কোনও stackসম্পত্তি নেই, তবে throwকীওয়ার্ড সেট sourceURLএবং lineনিক্ষেপ করা হচ্ছে এমন বস্তুর বৈশিষ্ট্য। এই জিনিসগুলি সঠিক হওয়ার গ্যারান্টিযুক্ত।

আমি ব্যবহৃত পরীক্ষার কেসগুলি এখানে পাওয়া যাবে: জাভাস্ক্রিপ্ট স্ব-তৈরি ত্রুটিযুক্ত বস্তুর তুলনা


19
আপনি this.name = 'MyError' ফাংশনটির বাইরের অংশটি সরিয়ে এটিকে পরিবর্তন করতে পারেন MyError.prototype.name = 'MyError'
ড্যানিয়েল বিয়ার্ডসলে

36
এটি এখানে একমাত্র সঠিক উত্তর, যদিও শৈলীর বিষয় হিসাবে, আমি সম্ভবত এটি এটি লিখতাম। function MyError(message) { this.message = message; this.stack = Error().stack; } MyError.prototype = Object.create(Error.prototype); MyError.prototype.name = "MyError";
kybernetikos

11
আমি যোগ চাই MyError.prototype.constructor = MyErrorখুব।
ভারত খাত্রি

3
ES6 এ ত্রুটি। সমস্ত (এটি, বার্তা); শুরু করা উচিত this, তাই না?
4esn0k

4
মাইআরআর.প্রোটোটাইপ = অবজেক্ট.create (ত্রুটি.প্রোটোটাইপ);
রবিন পাখির মতো

170

ES6 এ:

class MyError extends Error {
  constructor(message) {
    super(message);
    this.name = 'MyError';
  }
}

সূত্র


53
উল্লেখযোগ্য যে উল্লেখ করা যায় না যে আপনি যদি ব্যাপেলের মতো ট্রান্সপ্লেলারের মাধ্যমে ES6 বৈশিষ্ট্যগুলি ব্যবহার করেন তবে সাবক্লাসগুলি অবশ্যই একটি শ্রেণি প্রসারিত করতে পারে।
আয়েদান

6
আপনি যদি ব্যাবেল ব্যবহার করছেন এবং নোড> 5.x এ থাকেন তবে আপনি এস ২০১৫ প্রিসেটটি ব্যবহার করবেন না তবে npmjs.com/package/babel-preset-node5 আপনাকে দেশীয়
এস 6

2
এটি সম্ভব হলে এটি করার সর্বোত্তম উপায়। কাস্টম ত্রুটিগুলি ক্রোম এবং ফায়ারফক্স উভয়গুলিতে নিয়মিত ত্রুটির মতো আচরণ করে (এবং সম্ভবত অন্যান্য ব্রাউজারগুলিও)।
ম্যাট ব্রাউন

2
ব্রাউজারগুলির জন্য, নোট করুন যে আপনি রানটাইমে ক্লাসগুলির জন্য সমর্থন সনাক্ত করতে পারেন এবং সেই অনুসারে কোনও শ্রেণিবদ্ধ সংস্করণে ফিরে যেতে পারেন। সনাক্তকরণের কোড:var supportsClasses = false; try {eval('class X{}'); supportsClasses = true;} catch (e) {}
ম্যাট ব্রাউন

31
রক্ষণাবেক্ষণের স্বাচ্ছন্দ্যের জন্যthis.name = this.constructor.name; পরিবর্তে ব্যবহার করুন।
Ван

51

সংক্ষেপে:

  • আপনি যদি ট্রান্সপোর্টার ছাড়াই ES6 ব্যবহার করছেন :

    class CustomError extends Error { /* ... */}
  • আপনি যদি ব্যাবেল ট্রান্সপোর্টার ব্যবহার করেন :

বিকল্প 1: ব্যাবেল-প্লাগইন-ট্রান্সফর্ম-বিল্টইন-প্রসারিত ব্যবহার করুন

বিকল্প 2: এটি নিজেই করুন (একই লাইব্রেরি থেকে অনুপ্রাণিত)

    function CustomError(...args) {
      const instance = Reflect.construct(Error, args);
      Reflect.setPrototypeOf(instance, Reflect.getPrototypeOf(this));
      return instance;
    }
    CustomError.prototype = Object.create(Error.prototype, {
      constructor: {
        value: Error,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
    Reflect.setPrototypeOf(CustomError, Error);
  • আপনি যদি খাঁটি ES5 ব্যবহার করেন :

    function CustomError(message, fileName, lineNumber) {
      var instance = new Error(message, fileName, lineNumber);
      Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
      return instance;
    }
    CustomError.prototype = Object.create(Error.prototype, {
      constructor: {
        value: Error,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
    if (Object.setPrototypeOf){
        Object.setPrototypeOf(CustomError, Error);
    } else {
        CustomError.__proto__ = Error;
    }
  • বিকল্প: ক্লাস্টারফ্রোবিক কাঠামো ব্যবহার করুন

ব্যাখ্যা:

ES6 এবং ব্যাবেল ব্যবহার করে ত্রুটি শ্রেণীর বর্ধন কেন একটি সমস্যা?

কারণ কাস্টমআরারের একটি উদাহরণ আর এরূপে স্বীকৃত নয়।

class CustomError extends Error {}
console.log(new CustomError('test') instanceof Error);// true
console.log(new CustomError('test') instanceof CustomError);// false

বস্তুত, হট্টগোল অফিসিয়াল নথিপত্র থেকে, আপনি কোন বিল্ট-ইন জাভাস্ক্রিপ্ট শ্রেণীর প্রসারিত করতে পারবে না যেমন Date, Array, DOMবা Error

বিষয়টি এখানে বর্ণিত হয়েছে:

অন্যান্য এসও উত্তর সম্পর্কে কি?

প্রদত্ত সমস্ত উত্তর সমস্যার সমাধান করে instanceofতবে আপনি নিয়মিত ত্রুটি হারাবেন console.log:

console.log(new CustomError('test'));
// output:
// CustomError {name: "MyError", message: "test", stack: "Error↵    at CustomError (<anonymous>:4:19)↵    at <anonymous>:1:5"}

উপরে উল্লিখিত পদ্ধতিটি ব্যবহার করার সময়, আপনি কেবল instanceofসমস্যাটি সমাধান করেন না তবে আপনি নিয়মিত ত্রুটিটিও রাখেন console.log:

console.log(new CustomError('test'));
// output:
// Error: test
//     at CustomError (<anonymous>:2:32)
//     at <anonymous>:1:5

1
class CustomError extends Error { /* ... */}সঠিকভাবে বিক্রেতা-নির্দিষ্ট আর্গুমেন্টগুলি হ্যান্ডেল করে না ( lineNumberইত্যাদি), 'ইএস 6 সিনট্যাক্স সহ জাভাস্ক্রিপ্টে ত্রুটি প্রসারিত করা' বাবেল নির্দিষ্ট, আপনার ES5 সমাধান ব্যবহার করে constএবং এটি কাস্টম আর্গুমেন্টগুলি পরিচালনা করে না।
ইনডোলারিং

খুব সম্পূর্ণ উত্তর।
ড্যানিয়েল অরল্যান্ডো

এটি আসলে সর্বাধিক বিস্তৃত সমাধান সরবরাহ করে এবং বিভিন্ন টুকরো কেন প্রয়োজনীয় তা ব্যাখ্যা করে। অনেক ধন্যবাদ জেবিই!
অ্যান্ড্রুসথপাউ

এটি "ত্রুটি" থেকে উত্তরাধিকার সূত্রে সমস্যা সমাধানে আমাকে সহায়তা করেছে। দু'ঘন্টার দুঃস্বপ্ন!
আইলিয়ান পিনজারু

2
console.log(new CustomError('test') instanceof CustomError);// falseলেখার সময় যে সমস্যাটি ছিল তা সত্য ছিল তবে এখন তা সমাধান হয়েছে বলে মনে করা যায় না। প্রকৃতপক্ষে উত্তরের সাথে যুক্ত সমস্যাটি সমাধান হয়ে গেছে এবং আমরা এখানে সঠিক আচরণটি পরীক্ষা করতে পারি এবং আরইপিএলে কোডটি আটকানো এবং সঠিক প্রোটোটাইপ শৃঙ্খলে এটি কীভাবে সঠিকভাবে স্থানান্তরিত হয় তা দেখে।
নোবিটা

44

সম্পাদনা: মন্তব্য পড়ুন। এটি কেবল ভি 8-এ ভালভাবে কাজ করে (ক্রোম / নোড.জেএস) আমার উদ্দেশ্য ছিল ক্রস-ব্রাউজার সমাধান সরবরাহ করা, যা সমস্ত ব্রাউজারগুলিতে কাজ করবে এবং যেখানে সমর্থন রয়েছে সেখানে স্ট্যাক ট্রেস সরবরাহ করবে।

সম্পাদনা: আরও সম্পাদনার অনুমতি দেওয়ার জন্য আমি এই সম্প্রদায়টি উইকি তৈরি করেছি।

ভি 8 এর জন্য সলিউশন (ক্রোম / নোড.জেএস), ফায়ারফক্সে কাজ করে এবং প্রায়শই আইই তে সঠিকভাবে কাজ করতে পরিবর্তন করা যেতে পারে। (পোস্টের শেষে দেখুন)

function UserError(message) {
  this.constructor.prototype.__proto__ = Error.prototype // Make this an instanceof Error.
  Error.call(this) // Does not seem necessary. Perhaps remove this line?
  Error.captureStackTrace(this, this.constructor) // Creates the this.stack getter
  this.name = this.constructor.name; // Used to cause messages like "UserError: message" instead of the default "Error: message"
  this.message = message; // Used to set the message
}

"আমাকে কোডটি দেখান!" এর মূল পোস্ট

সংক্ষিপ্ত সংস্করণ:

function UserError(message) {
  this.constructor.prototype.__proto__ = Error.prototype
  Error.captureStackTrace(this, this.constructor)
  this.name = this.constructor.name
  this.message = message
}

আমি this.constructor.prototype.__proto__ = Error.prototypeসমস্ত কোড একসাথে রাখতে ফাংশনের ভিতরে রাখি । তবে আপনি এটির this.constructorসাথে প্রতিস্থাপনও করতে পারেন UserErrorএবং এটি আপনাকে কোডটি ফাংশনের বাইরে নিয়ে যাওয়ার অনুমতি দেয়, সুতরাং এটি কেবল একবার কল হয়।

আপনি যদি সেই রাস্তাটিতে যান তবে নিশ্চিত হন যে আপনি প্রথমবার নিক্ষেপ করার আগে সেই লাইনটি কল করেছিলেনUserError

এই ক্যাভিয়েটটি ফাংশনটি প্রয়োগ করে না, কারণ ক্রমগুলি প্রথমে তৈরি করা হয়েছে, অর্ডার নির্বিশেষে কোনও ব্যাপার নয়। সুতরাং, আপনি কোনও সমস্যা ছাড়াই ফাংশনটি ফাইলের শেষের দিকে যেতে পারবেন।

ব্রাউজার সামঞ্জস্য

ফায়ারফক্স এবং ক্রোমে কাজ করে (এবং নোড.জেএস) এবং সমস্ত প্রতিশ্রুতি পূরণ করে।

ইন্টারনেট এক্সপ্লোরার নিম্নলিখিত ব্যর্থ হয়

  • ত্রুটিগুলি err.stackদিয়ে শুরু করতে হবে না , তাই "এটি আমার দোষ নয়"।

  • Error.captureStackTrace(this, this.constructor) অস্তিত্ব নেই তাই আপনার মতো অন্য কিছু করা দরকার

    if(Error.captureStackTrace) // AKA if not IE
        Error.captureStackTrace(this, this.constructor)
  • toStringআপনি সাবক্লাস করার সময় অস্তিত্ব বন্ধ করে দেয় Error। সুতরাং আপনারও যোগ করা দরকার।

    else
        this.toString = function () { return this.name + ': ' + this.message }
  • আপনি যদি আপনার আগে কিছুক্ষণ সময় না UserErrorচালিয়ে থাকেন instanceof Errorতবে IE আপনাকে এটিকে বিবেচনা করবে নাthrow UserError

    UserError.prototype = Error.prototype

16
আমি মনে করি না ফায়ারফক্সের আসলে ক্যাপচারস্ট্যাকট্রেস রয়েছে। এটি একটি ভি 8 এক্সটেনশন এবং এটি আমার জন্য ফায়ারফক্সে অপরিজ্ঞাত, এবং ফায়ারফক্সের পক্ষে এটি সমর্থন করে এমন কোনও রেফারেন্স আমি পাই না। (যদিও ধন্যবাদ!)
জেফ

5
Error.call(this)প্রকৃতপক্ষে কিছুই করছে যেহেতু এটি ফেরৎ পরিবর্তন চেয়ে একটি ত্রুটি বরং this
কায়বারনেটিকোস

1
নোড.জেএস এর জন্য দুর্দান্ত কাজ করে
রুডলফ মিজারিং

1
UserError.prototype = Error.prototypeবিভ্রান্তিকর। এটি উত্তরাধিকার করে না, এটি তাদেরকে একই বর্গ করে তোলে ।
হালসিওন

1
আমি বিশ্বাস করি কমপক্ষে বর্তমান ব্রাউজারগুলির জন্য Object.setPrototypeOf(this.constructor.prototype, Error.prototype)পছন্দ করা this.constructor.prototype.__proto__ = Error.prototypeহয়।
ChrisV

29

করতে boilerplate, এড়ানো ত্রুটির যে বিভিন্ন ধরনের জন্য, আমি একটি মধ্যে সমাধান কিছু জ্ঞান মিলিত  createErrorTypeফাংশন:

function createErrorType(name, init) {
  function E(message) {
    if (!Error.captureStackTrace)
      this.stack = (new Error()).stack;
    else
      Error.captureStackTrace(this, this.constructor);
    this.message = message;
    init && init.apply(this, arguments);
  }
  E.prototype = new Error();
  E.prototype.name = name;
  E.prototype.constructor = E;
  return E;
}

তারপরে আপনি নতুন ত্রুটির প্রকারগুলি সহজেই নিম্নলিখিত হিসাবে সংজ্ঞায়িত করতে পারেন :

var NameError = createErrorType('NameError', function (name, invalidChar) {
  this.message = 'The name ' + name + ' may not contain ' + invalidChar;
});

var UnboundError = createErrorType('UnboundError', function (variableName) {
  this.message = 'Variable ' + variableName + ' is not bound';
});

আপনার এখনও লাইনের প্রয়োজনের কোনও কারণ আছে this.name = name;?
পিটার তাসেং

@ পিটারটসেং যেহেতু nameইতিমধ্যে প্রোটোটাইপে সেট করা আছে, এটি আর প্রয়োজন হয় না। আমি এটি সরিয়েছি। ধন্যবাদ!
রুবেন ভার্বার্গ

27

2018 সালে , আমি মনে করি এটি সেরা উপায়; যা আই 9 + এবং আধুনিক ব্রাউজারগুলিকে সমর্থন করে।

আপডেট : বিভিন্ন বাস্তবায়নের তুলনায় এই পরীক্ষাটি এবং রেপোটি দেখুন ।

function CustomError(message) {
    Object.defineProperty(this, 'name', {
        enumerable: false,
        writable: false,
        value: 'CustomError'
    });

    Object.defineProperty(this, 'message', {
        enumerable: false,
        writable: true,
        value: message
    });

    if (Error.hasOwnProperty('captureStackTrace')) { // V8
        Error.captureStackTrace(this, CustomError);
    } else {
        Object.defineProperty(this, 'stack', {
            enumerable: false,
            writable: false,
            value: (new Error(message)).stack
        });
    }
}

if (typeof Object.setPrototypeOf === 'function') {
    Object.setPrototypeOf(CustomError.prototype, Error.prototype);
} else {
    CustomError.prototype = Object.create(Error.prototype, {
        constructor: { value: CustomError }
    });
}

এছাড়াও সাবধান যে __proto__সম্পত্তি হ্রাস করা হয়েছে যা অন্যান্য উত্তরে ব্যাপকভাবে ব্যবহৃত হয়।


1
আপনি কেন ব্যবহার করছেন setPrototypeOf()? কমপক্ষে এমডিএন অনুসারে, আপনি কেবল .prototypeকনস্ট্রাক্টরের উপর সম্পত্তি সেট করে একই জিনিসটি সম্পাদন elseকরতে পারলে সাধারণত এটি ব্যবহার করতে নিরুৎসাহিত করা হয় (যেমন আপনি ব্রাউজগুলির মধ্যে নেই যা ব্রাউজগুলির জন্য ব্লকে করছেন setPrototypeOf)।
ম্যাট ব্রাউন

একটি বস্তুর প্রোটোটাইপ বদল করা সমস্ত একসঙ্গে নিরুৎসাহিত, তাই না setPrototypeOf। তবে এখনও যদি আপনার এটির প্রয়োজন হয় (যেমন ওপি জিজ্ঞাসা করে) তবে আপনার অন্তর্নির্মিত পদ্ধতিটি ব্যবহার করা উচিত। এমডিএন সূচিত হিসাবে, এটি কোনও সামগ্রীর প্রোটোটাইপ সেট করার উপযুক্ত উপায় হিসাবে বিবেচিত হয়। অন্য কথায়, এমডিএন বলেছে যে প্রোটোটাইপটি পরিবর্তন করবেন না (কারণ এটি কার্যকারিতা এবং অপ্টিমাইজেশানকে প্রভাবিত করে) তবে আপনাকে যদি ব্যবহার করতে হয় তবে তা ব্যবহার করুন setPrototypeOf
ওনুর ইল্ডারিয়াম

আমার বক্তব্যটি হ'ল আমার মনে হয় না যে এখানে আপনার প্রোটোটাইপটি বদলাতে হবে। আপনি কেবল নীচে আপনার লাইনটি ব্যবহার করতে পারেন ( CustomError.prototype = Object.create(Error.prototype))। এছাড়াও, Object.setPrototypeOf(CustomError, Error.prototype)নতুন উদাহরণগুলির জন্য প্রোটোটাইপ নির্দিষ্ট করার চেয়ে কনস্ট্রাক্টরের নিজেই প্রোটোটাইপ সেট করা হচ্ছে CustomError। যাই হোক, 2016 সালে আমার মনে হয় আসলে ত্রুটি প্রসারিত একটি ভাল উপায়, যদিও আমি এখনও figuring আউট করছি কিভাবে একসঙ্গে এটি ব্যবহার করতে হট্টগোল সঙ্গে github.com/loganfsmyth/babel-plugin-transform-builtin-extend/...
ম্যাট ব্রাউনি

CustomError.prototype = Object.create(Error.prototype)প্রোটোটাইপ পরিবর্তন করা হয়। ইএস 5 তে অন্তর্নির্মিত প্রসারিত / উত্তরাধিকার যুক্তি না থাকায় আপনাকে এটিকে পরিবর্তন করতে হবে। আমি নিশ্চিত আপনি বাবেল প্লাগইনটি একই জিনিসগুলি করে।
ওনুর ইল্ডারিয়াম

1
আমি এখানে একটি সংক্ষিপ্তসার দেখিয়েছি যা ব্যবহার Object.setPrototypeOfকরে এখানে বোঝা যায় না, কমপক্ষে আপনি যেভাবে ব্যবহার করছেন তা নয়: gist.github.com/mbrowne/4af54767dcb3d529648f5a8aa11d6348 । সম্ভবত আপনি লিখতে চেয়েছিলেন Object.setPrototypeOf(CustomError.prototype, Error.prototype)- এটি কিছুটা আরও অর্থবোধ তৈরি করবে (যদিও এখনও কেবল সেটিংয়ের উপর কোনও লাভ দেয় না CustomError.prototype)।
ম্যাট ব্রাউন

19

সম্পূর্ণতার স্বার্থে - পূর্ববর্তী উত্তরগুলির মধ্যে কোনওটিই এই পদ্ধতির উল্লেখ করেনি - আপনি যদি নোড.জেএস এর সাথে কাজ করছেন এবং ব্রাউজারের সামঞ্জস্যতা সম্পর্কে যত্ন নিতে না চান তবে অন্তর্নির্মিত সাথে কাঙ্ক্ষিত প্রভাবটি অর্জন করা বেশ সহজ achieve inheritsএর utilমডিউল ( সরকারী দস্তাবেজ এখানে )।

উদাহরণস্বরূপ, ধরা যাক আপনি একটি কাস্টম ত্রুটি শ্রেণি তৈরি করতে চান যা প্রথম তর্ক হিসাবে ত্রুটি কোড এবং দ্বিতীয় তর্ক হিসাবে ত্রুটি বার্তা গ্রহণ করে:

ফাইল কাস্টম-ত্রুটি.জেএস :

'use strict';

var util = require('util');

function CustomError(code, message) {
  Error.captureStackTrace(this, CustomError);
  this.name = CustomError.name;
  this.code = code;
  this.message = message;
}

util.inherits(CustomError, Error);

module.exports = CustomError;

এখন আপনি তাত্ক্ষণিকভাবে এবং পাস / নিক্ষেপ করতে পারেন আপনার CustomError:

var CustomError = require('./path/to/custom-error');

// pass as the first argument to your callback
callback(new CustomError(404, 'Not found!'));

// or, if you are working with try/catch, throw it
throw new CustomError(500, 'Server Error!');

মনে রাখবেন, এই স্নিপেটের সাহায্যে স্ট্যাক ট্রেসের সঠিক ফাইলের নাম এবং লাইন থাকবে এবং ত্রুটির উদাহরণটির সঠিক নাম থাকবে!

captureStackTraceপদ্ধতিটির ব্যবহারের কারণে এটি ঘটে , যা stackলক্ষ্য বস্তুতে একটি সম্পত্তি তৈরি করে (এই ক্ষেত্রে, CustomErrorতাত্ক্ষণিক হচ্ছে)। এটি কীভাবে কাজ করে সে সম্পর্কে আরও তথ্যের জন্য এখানে ডকুমেন্টেশন চেক করুন


1
this.message = this.message;এটি কি ভুল বা এখনও কী পাগল জিনিস আমি জেএস সম্পর্কে জানি না?
অ্যালেক্স

1
আরে @ অ্যালেক্স আপনি পুরোপুরি ঠিক বলেছেন! এটি এখন স্থির। ধন্যবাদ!
ভিক্টর শ্রড্ডার

18

ক্রিসেন্ট ফ্রেশের উত্তর সর্বাধিক ভোট দেওয়া উত্তর বিভ্রান্তিকর। যদিও তার সতর্কবাণীগুলি অবৈধ, অন্যান্য সীমাবদ্ধতাগুলিও সেটিকে সম্বোধন করে না।

প্রথমত, ক্রিসেন্টের "ক্যাভেটস:" অনুচ্ছেদে যুক্তিটি অর্থবোধ করে না। ব্যাখ্যাটি বোঝায় যে "একগুচ্ছ যদি (অন্যথায় ত্রুটির উদাহরণ) ..." একাধিক ক্যাচ স্টেটমেন্টের সাথে তুলনা করা একরকম বোঝা বা ভার্জোজ od একক ক্যাচ ব্লকে একাধিক উদাহরণ বিবৃতিগুলি একাধিক ক্যাচ স্টেটমেন্টের মতোই সংক্ষিপ্ত - কোনও কৌশল ছাড়াই পরিষ্কার এবং সংক্ষিপ্ত কোড। এটি জাভার দুর্দান্ত থ্রোয়েবল-সাব-টাইপ-নির্দিষ্ট ত্রুটি পরিচালনা পরিচালনা করার দুর্দান্ত উপায়।

ডাব্লুআরটি "সাবক্লাসের বার্তা বৈশিষ্ট্যটি সেট হয় না" প্রদর্শিত হয়, আপনি যদি সঠিকভাবে নির্মিত ত্রুটি সাবক্লাস ব্যবহার করেন তবে তা নয়। আপনার নিজের ত্রুটিএক্স ত্রুটি সাবক্লাসটি তৈরি করতে, "ভায় মাইরার =" দিয়ে কোড ব্লকের সূচনাটি অনুলিপি করুন, একটি শব্দ "মাইআরর" পরিবর্তন করে "ত্রুটিএক্স" করুন। (আপনি যদি আপনার সাবক্লাসে কাস্টম পদ্ধতি যুক্ত করতে চান তবে নমুনার পাঠ্যটি অনুসরণ করুন)।

জাভাস্ক্রিপ্ট ত্রুটি সাবক্লাসিংয়ের আসল এবং উল্লেখযোগ্য সীমাবদ্ধতাটি হ'ল যে জাভাস্ক্রিপ্ট বাস্তবায়ন বা ডিবাগারগুলি স্ট্যাক ট্রেস এবং অবস্থান-ইনস্ট্যান্টেশন সম্পর্কিত ফায়ারফক্সের মতো ট্র্যাক করে এবং প্রতিবেদন করে, তেমনি আপনার নিজের ত্রুটি সাবক্লাস বাস্তবায়নের কোনও অবস্থানটি ইনস্ট্যান্টেশন পয়েন্ট হিসাবে রেকর্ড করা হবে শ্রেণি, যদিও আপনি যদি সরাসরি ত্রুটি ব্যবহার করেন তবে এটি সেই জায়গা যেখানে আপনি "নতুন ত্রুটি (...)" চালিয়েছিলেন। আইই ব্যবহারকারীরা সম্ভবত লক্ষ্য করবেন না, তবে এফএফ-তে ফায়ার বাগের ব্যবহারকারীরা এই ত্রুটিগুলির পাশাপাশি প্রতিবেদন করা অযথা ফাইলের নাম এবং লাইন নম্বর মানগুলি দেখতে পাবেন এবং প্রকৃত তাত্ক্ষণিক অবস্থানের জন্য স্ট্যাক ট্রেসটিতে উপাদান # 1 এ ড্রিল করতে হবে।


আমি কি এটি সঠিকভাবে পেয়েছি - আপনি যদি সাবক্লাস না করে এবং সরাসরি নতুন ত্রুটি (...) ব্যবহার না করেন তবে ফাইলের নাম এবং লাইনটি সঠিকভাবে প্রতিবেদন করা হচ্ছে? এবং আপনি মূলত বলছেন যে অনুশীলনে (আসল এবং কেবল সেক্সি বা আলংকারিক ধরণের নয়) সাবক্লাসিং ত্রুটিগুলির কোনও ধারণা নেই?
জয়য়ারজো

6
এই উত্তরটি Crescent Fresh'sমুছে ফেলা হয়েছে বলে কিছু বিভ্রান্তিকর !
পিটার

এটা কি এখনও আছে? developer.mozilla.org/en-US/docs/Web/JavaScript/References/… লাইন নম্বরটি 2 নয় যেখানে নতুন বলা হয়েছিল
মুহাম্মদ উমর

13

কীভাবে এই সমাধান?

আপনার কাস্টম ত্রুটিটি ব্যবহার করার পরিবর্তে ব্যবহার করুন:

throw new MyError("Oops!");

আপনি ত্রুটি বস্তুটি মুড়িয়ে ফেলবেন (ধরণের ডেকোরের মতো):

throw new MyError(Error("Oops!"));

এটি নিশ্চিত করে যে সমস্ত বৈশিষ্ট্যগুলি সঠিক, যেমন স্ট্যাক, ফাইল নাম লাইন নাম্বার, এবং সেল্টেরা are

তারপরে আপনাকে যা করতে হবে তা হ'ল বৈশিষ্ট্যগুলির অনুলিপি করা, বা তাদের জন্য গিটারগুলি সংজ্ঞায়িত করা। গেটার্স (আই 9) ব্যবহার করে এখানে একটি উদাহরণ দেওয়া হয়েছে:

function MyError(wrapped)
{
        this.wrapped = wrapped;
        this.wrapped.name = 'MyError';
}

function wrap(attr)
{
        Object.defineProperty(MyError.prototype, attr, {
                get: function()
                {
                        return this.wrapped[attr];
                }
        });
}

MyError.prototype = Object.create(Error.prototype);
MyError.prototype.constructor = MyError;

wrap('name');
wrap('message');
wrap('stack');
wrap('fileName');
wrap('lineNumber');
wrap('columnNumber');

MyError.prototype.toString = function()
{
        return this.wrapped.toString();
};

1
এই সমাধানটি আমি এনপিএম প্যাকেজ হিসাবে প্রকাশ করেছি: npmjs.com/package/throwable
জোউই

অবিশ্বাস্যভাবে মার্জিত সমাধান, ভাগ করে নেওয়ার জন্য ধন্যবাদ! একটি প্রকরণ: new MyErr (arg1, arg2, new Error())এবং মাইআরআর কন্সট্রাক্টরে আমরা Object.assignশেষ this
আর্গের

আমি এই পছন্দ। উত্তরাধিকারের পরিবর্তে এনক্যাপসুলেশন ব্যবহার করে আপনি একটি সীমাবদ্ধতা বাইপাস করেন।
জেনি ও'রিলি

13

কিছু লোক যেমন বলেছে, এটি ES6 এর সাথে মোটামুটি সহজ:

class CustomError extends Error { }

সুতরাং আমি চেষ্টা করেছি যে আমার অ্যাপ্লিকেশনটির মধ্যে, (কৌণিক, টাইপস্ক্রিপ্ট) এবং এটি কার্যকর হয়নি। কিছু সময় পরে আমি দেখতে পেয়েছি যে সমস্যা টাইপসক্রিপ্ট থেকে আসছে: ও

Https://github.com/Mic Microsoft/ TypeScript/ issues/ 13965 দেখুন

এটি খুব বিরক্তিকর কারণ যদি আপনি এটি করেন:

class CustomError extends Error {}


try {
  throw new CustomError()
} catch(e) {
  if (e instanceof CustomError) {
    console.log('Custom error');
  } else {
    console.log('Basic error');
  }
}

নোডে বা সরাসরি আপনার ব্রাউজারে এটি প্রদর্শিত হবে: Custom error

টাইপসক্রিপ্ট খেলার মাঠে আপনার প্রকল্পে টাইপসক্রিপ্ট দিয়ে এটি চালানোর চেষ্টা করুন, এটি প্রদর্শিত হবে Basic error...

সমাধান নিম্নলিখিতটি করা হয়:

class CustomError extends Error {
  // we have to do the following because of: https://github.com/Microsoft/TypeScript/issues/13965
  // otherwise we cannot use instanceof later to catch a given type
  public __proto__: Error;

  constructor(message?: string) {
    const trueProto = new.target.prototype;
    super(message);

    this.__proto__ = trueProto;
  }
}

10

আমার সমাধান সরবরাহ করা অন্যান্য উত্তরগুলির চেয়ে বেশি সহজ এবং ডাউনসাইড নেই।

এটি ত্রুটির প্রোটোটাইপ চেইন এবং ত্রুটির সমস্ত বৈশিষ্ট্যগুলির নির্দিষ্ট নির্দিষ্ট জ্ঞান ছাড়াই সংরক্ষণ করে। এটি ক্রোম, ফায়ারফক্স, নোড এবং আইই ১১ এ পরীক্ষা করা হয়েছে।

একমাত্র সীমাবদ্ধতা হ'ল কল স্ট্যাকের শীর্ষে একটি অতিরিক্ত প্রবেশ। তবে তা সহজেই উপেক্ষা করা হয়।

দুটি কাস্টম পরামিতি সহ এখানে একটি উদাহরণ:

function CustomError(message, param1, param2) {
    var err = new Error(message);
    Object.setPrototypeOf(err, CustomError.prototype);

    err.param1 = param1;
    err.param2 = param2;

    return err;
}

CustomError.prototype = Object.create(
    Error.prototype,
    {name: {value: 'CustomError', enumerable: false}}
);

ব্যবহারের উদাহরণ:

try {
    throw new CustomError('Something Unexpected Happened!', 1234, 'neat');
} catch (ex) {
    console.log(ex.name); //CustomError
    console.log(ex.message); //Something Unexpected Happened!
    console.log(ex.param1); //1234
    console.log(ex.param2); //neat
    console.log(ex.stack); //stacktrace
    console.log(ex instanceof Error); //true
    console.log(ex instanceof CustomError); //true
}

পরিবেশের জন্য যা সেটপ্রোটোটাইপএফের পলিফিলের প্রয়োজন:

Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {
    obj.__proto__ = proto;
    return obj;
};

1
আমার উত্তরে নথিবদ্ধ হিসাবে, এই সমাধানটি ফায়ারফক্স বা অন্যান্য ব্রাউজারগুলিতে সমস্যার সৃষ্টি করতে পারে যা কেবল কনসোলে স্ট্যাক ট্রেসের প্রথম লাইনে লগইন করে
জোনাথন বেন

এটিই কেবলমাত্র আমি খুঁজে পেয়েছি যে ES5 এর সাথে ভাল কাজ করে (ES6 ক্লাস ব্যবহার করে খুব ভাল কাজ করে)। ত্রুটিগুলি অন্যান্য উত্তরের চেয়ে ক্রোমিয়াম ডেভটুলগুলিতে অনেক দুর্দান্তভাবে প্রদর্শন করে।
বেন গুবলার

দ্রষ্টব্য: আপনি যদি এই সমাধানটি টাইপস্ক্রিপ্ট দিয়ে ব্যবহার করে থাকেন তবে আপনার throw CustomError('err')পরিবর্তে চালানো আবশ্যকthrow new CustomError('err')
বেন গাবলার

8

উপরের উদাহরণে Error.apply(এছাড়াও Error.call) আমার জন্য কিছুই করে না (ফায়ারফক্স 3.6 / ক্রোম 5) আমি ব্যবহার করি না এমন একটি হ'ল:

function MyError(message, fileName, lineNumber) {
    var err = new Error();

    if (err.stack) {
        // remove one stack level:
        if (typeof(Components) != 'undefined') {
            // Mozilla:
            this.stack = err.stack.substring(err.stack.indexOf('\n')+1);
        }
        else if (typeof(chrome) != 'undefined' || typeof(process) != 'undefined') {
            // Google Chrome/Node.js:
            this.stack = err.stack.replace(/\n[^\n]*/,'');
        }
        else {
            this.stack = err.stack;
        }
    }
    this.message    = message    === undefined ? err.message    : message;
    this.fileName   = fileName   === undefined ? err.fileName   : fileName;
    this.lineNumber = lineNumber === undefined ? err.lineNumber : lineNumber;
}

MyError.prototype = new Error();
MyError.prototype.constructor = MyError;
MyError.prototype.name = 'MyError';

5

নোডে যেমন অন্যেরা বলেছেন, এটি সহজ:

class DumbError extends Error {
    constructor(foo = 'bar', ...params) {
        super(...params);

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

        this.name = 'DumbError';

        this.foo = foo;
        this.date = new Date();
    }
}

try {
    let x = 3;
    if (x < 10) {
        throw new DumbError();
    }
} catch (error) {
    console.log(error);
}

3

আমি অন্যরা যা ইতিমধ্যে বলেছে তাতে কেবল যুক্ত করতে চাই:

কাস্টম ত্রুটি শ্রেণীর স্ট্যাক ট্রেসটিতে সঠিকভাবে প্রদর্শিত হচ্ছে তা নিশ্চিত করার জন্য, আপনাকে কাস্টম ত্রুটি শ্রেণীর প্রোটোটাইপের নাম সম্পত্তিটি কাস্টম ত্রুটি শ্রেণির নাম বৈশিষ্ট্যে সেট করতে হবে। এটি আমার অর্থ:

CustomError.prototype = Error.prototype;
CustomError.prototype.name = 'CustomError';

সুতরাং পুরো উদাহরণটি হ'ল:

    var CustomError = function(message) {
        var err = new Error(message);
        err.name = 'CustomError';
        this.name = err.name;
        this.message = err.message;
        //check if there is a stack property supported in browser
        if (err.stack) {
            this.stack = err.stack;
        }
        //we should define how our toString function works as this will be used internally
        //by the browser's stack trace generation function
        this.toString = function() {
           return this.name + ': ' + this.message;
        };
    };
    CustomError.prototype = new Error();
    CustomError.prototype.name = 'CustomError';

সব কিছু বলা এবং হয়ে গেলে, আপনি আপনার নতুন ব্যতিক্রম ছুঁড়ে ফেলেছেন এবং এটি দেখতে এটির মতো দেখাচ্ছে (আমি আলস্যভাবে ক্রোম দেব সরঞ্জামগুলিতে এটি চেষ্টা করেছি):

CustomError: Stuff Happened. GASP!
    at Error.CustomError (<anonymous>:3:19)
    at <anonymous>:2:7
    at Object.InjectedScript._evaluateOn (<anonymous>:603:39)
    at Object.InjectedScript._evaluateAndWrap (<anonymous>:562:52)
    at Object.InjectedScript.evaluate (<anonymous>:481:21)

5
এটি কি সমস্ত ত্রুটির দৃষ্টান্তের জন্য নামের সম্পত্তিটিকে ওভাররাইট করে না ?
পানজি

@ পাঞ্জি আপনি সঠিক আছেন আমি আমার ছোট বাগ ঠিক করেছি। সতর্ক থাকুন জন্য ধন্যবাদ!
গৌতম সি।

3

আমার 2 সেন্ট:

অন্য উত্তর কেন?

ক) Error.stackসম্পত্তিটি অ্যাক্সেস করার কারণে (কিছু উত্তর হিসাবে) একটি বৃহত পারফরম্যান্স পেনাল্টি রয়েছে।

খ) কারণ এটি কেবল একটি লাইন।

গ) কারণ https://developer.mozilla.org/en-US/docs/Web/ জাভা স্ক্রিপ্ট / রেফারেন্স / গ্লোবাল_অবজেক্টস / এরর এর সমাধানটি স্ট্যাকের তথ্য সংরক্ষণ করে বলে মনে হচ্ছে না।

//MyError class constructor
function MyError(msg){
    this.__proto__.__proto__ = Error.apply(null, arguments);
};

ব্যবহার উদাহরণ

http://jsfiddle.net/luciotato/xXyeB/

এটার কাজ কি?

this.__proto__.__proto__হ'ল MyError.prototype.__proto__, সুতরাং এটি __proto__MyError এর সমস্ত ইনস্ট্যান্সের জন্য নির্দিষ্ট সদ্য নির্মিত ত্রুটিতে সেট করছে । এটি MyError শ্রেণীর বৈশিষ্ট্য এবং পদ্ধতি রাখে এবং নতুন ত্রুটি বৈশিষ্ট্যগুলি (। স্ট্যাক সহ) __proto__শৃঙ্খলে রাখে।

স্পষ্ট সমস্যা:

দরকারী স্ট্যাক তথ্যের সাথে আপনার কাছে মাইআরারের একাধিক উদাহরণ থাকতে পারে না।

আপনি যদি পুরোপুরি না বুঝতে পারেন তবে এই সমাধানটি ব্যবহার করবেন না this.__proto__.__proto__=


2

যেহেতু জাভাস্ক্রিপ্ট ব্যতিক্রমগুলি উপ-শ্রেণীর পক্ষে কঠিন, তাই আমি উপ-শ্রেণি করি না। আমি কেবলমাত্র একটি নতুন ব্যতিক্রম শ্রেণি তৈরি করেছি এবং এর ভিতরে একটি ত্রুটি ব্যবহার করব। আমি ত্রুটি.নাম সম্পত্তিটি পরিবর্তন করেছি যাতে এটি কনসোলে আমার কাস্টম ব্যতিক্রমের মতো দেখায়:

var InvalidInputError = function(message) {
    var error = new Error(message);
    error.name = 'InvalidInputError';
    return error;
};

উপরের নতুন ব্যতিক্রমটি কেবল একটি নিয়মিত ত্রুটির মতো নিক্ষেপ করা যেতে পারে এবং এটি প্রত্যাশা অনুযায়ী কাজ করবে, উদাহরণস্বরূপ:

throw new InvalidInputError("Input must be a string");
// Output: Uncaught InvalidInputError: Input must be a string 

ক্যাভ্যাট: স্ট্যাক ট্রেসটি সঠিক নয়, কারণ এটি আপনাকে এনে দেবে যেখানে নতুন ত্রুটি তৈরি হয়েছে এবং যেখানে আপনি ফেলেছেন সেখানে নয়। এটি ক্রোমে কোনও বড় বিষয় নয় কারণ এটি আপনাকে সরাসরি কনসোলে একটি সম্পূর্ণ স্ট্যাক ট্রেস সরবরাহ করে। তবে এটি ফায়ারফক্সে আরও সমস্যাযুক্ত, উদাহরণস্বরূপ।


এটি ক্ষেত্রে ব্যর্থ হয়m = new InvalidInputError(); dontThrowMeYet(m);
এরিক

@ এরিক আমি সম্মত, তবে এটি বেশ ছোট সীমাবদ্ধতার মতো বলে মনে হচ্ছে। আমার আগে কখনও কোনও ব্যতিক্রম বস্তু ইনস্ট্যান্ট করার দরকার হয়নি (উপরে আমার কোড নমুনার মতো মেটা-প্রোগ্রামিং ব্যবহার বাদে)। এটা কি সত্যিই আপনার সমস্যা?
জোনাথন বেন

হ্যাঁ, আচরণটি একই বলে মনে হচ্ছে, তাই আমি আমার উত্তরটি পরিবর্তন করব। আমি স্ট্যাক ট্রেস দিয়ে 100% সন্তুষ্ট নই, যা আপনাকে ফায়ারফক্স এবং ক্রোমের "ভার ত্রুটি" লাইনে নিয়ে আসে
জোনাথন বেন

1
@ জোনাথনবেন আমি পার্টিতে আসার জন্য অনেক দেরি করছি, তাই সম্ভবত আপনি এটি ইতিমধ্যে বেছে নিয়েছেন। আমি যখন অ্যাসিনক্রোনাস প্রোগ্রামিং এবং প্রতিশ্রুতি ব্যবহার করি তখন আমি প্রায়শই একটি ব্যতিক্রম বস্তু ইনস্ট্যান্ট করি। @ এরিক নামের অনুসরণ, আমি প্রায়ই ব্যবহার m = new ...তারপর Promise.reject(m)। এটি কোনও প্রয়োজনীয়তা নয়, তবে কোডটি পড়া সহজ।
বাল্ডএগল

1
@ জোনাথনবেন: (তিনি) ১৪ ই অক্টোবরে, আপনি মনে করেন কোনও ব্যতিক্রম বস্তু নিক্ষেপ করার আগে তা ইনস্ট্যান্ট করা বিরল হবে। আমি এটি করার সময়টির একটি উদাহরণ দিয়েছি। আমি এটি সাধারণ বলব না, তবে যখন চাই তখন তা করা সহজ। এবং, আমার কোডটি আরও পঠনযোগ্য কারণ তাত্ক্ষণিকভাবে সমস্ত এক লাইনে এবং সমস্ত অন্যটিতে প্রত্যাখ্যান করা। আমি এটা আশা করি!
বাল্ডএগল

2

মোহসেনের উত্তরে যেমন উল্লেখ করা হয়েছে, ES6 এ ক্লাস ব্যবহার করে ত্রুটিগুলি বাড়ানো সম্ভব। এটি অনেক সহজ এবং তাদের আচরণ দেশীয় ত্রুটির সাথে আরও সুসংগত ... তবে দুর্ভাগ্যক্রমে ব্রাউজারে এটি ব্যবহার করা সহজ বিষয় নয় যদি আপনার প্রাক-ইএস 6 ব্রাউজারগুলি সমর্থন করতে হয়। কীভাবে এটি প্রয়োগ করা যেতে পারে তার কয়েকটি নোটগুলির জন্য নীচে দেখুন, তবে এর মধ্যে আমি একটি তুলনামূলক সহজ পদ্ধতির পরামর্শ দিচ্ছি যা অন্যান্য উত্তরগুলির থেকে সেরা পরামর্শগুলিকে অন্তর্ভুক্ত করে:

function CustomError(message) {
    //This is for future compatibility with the ES6 version, which
    //would display a similar message if invoked without the
    //`new` operator.
    if (!(this instanceof CustomError)) {
        throw new TypeError("Constructor 'CustomError' cannot be invoked without 'new'");
    }
    this.message = message;

    //Stack trace in V8
    if (Error.captureStackTrace) {
       Error.captureStackTrace(this, CustomError);
    }
    else this.stack = (new Error).stack;
}
CustomError.prototype = Object.create(Error.prototype);
CustomError.prototype.name = 'CustomError';

ES6 এ এটি এতটা সহজ:

class CustomError extends Error {}

... এবং আপনি এর সাথে ES6 শ্রেণীর জন্য সমর্থন সনাক্ত করতে পারেন try {eval('class X{}'), তবে আপনি যদি পুরানো ব্রাউজারগুলি দ্বারা লোড হওয়া কোনও স্ক্রিপ্টে ES6 সংস্করণ অন্তর্ভুক্ত করার চেষ্টা করেন তবে আপনি একটি সিনট্যাক্স ত্রুটি পাবেন। সুতরাং সমস্ত ব্রাউজারগুলিকে সমর্থন করার একমাত্র উপায় eval()হ'ল ইএস 6 সমর্থনকারী ব্রাউজারগুলির জন্য একটি পৃথক স্ক্রিপ্ট গতিশীলভাবে লোড করা (যেমন এজেএক্সের মাধ্যমে বা )। আরও জটিলতা হ'ল এটি eval()সমস্ত পরিবেশে (সামগ্রী সুরক্ষা নীতিগুলির কারণে) সমর্থিত নয়, যা আপনার প্রকল্পের জন্য বিবেচনাযোগ্য হতে পারে বা নাও হতে পারে।

সুতরাং আপাতত, উপরের প্রথম পদ্ধতিটি বা কেবল Errorপ্রসারিত করার চেষ্টা না করে সরাসরি ব্যবহার করা এটিকে ব্যবহারিকভাবে এমন কোড হিসাবে কার্যকর করা যেতে পারে যা নন-ইএস 6 ব্রাউজারগুলিকে সমর্থন করা প্রয়োজন be

অন্য একটি পদ্ধতি রয়েছে যা কিছু লোক বিবেচনা করতে পারে, যা Object.setPrototypeOf()আপনার কাস্টম ত্রুটির ধরণের উদাহরণ হিসাবে এমন একটি ত্রুটিযুক্ত বস্তু তৈরি করতে যেখানে উপলব্ধ তা ব্যবহার করা হয় তবে এটি কনসোলে স্থানীয় ত্রুটির মতো দেখতে এবং আচরণ করে ( বেনের উত্তরের জন্য ধন্যবাদ সুপারিশ জন্য)। আমি এই পদ্ধতির গ্রহণ আমার এখানে: https://gist.github.com/mbrowne/fe45db61cea7858d11be933a998926a8 । তবে যে একদিন আমরা কেবল ES6 ব্যবহার করতে সক্ষম হব, ব্যক্তিগতভাবে আমি নিশ্চিত নই যে এই পদ্ধতির জটিলতা এটির পক্ষে উপযুক্ত।


1

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

function MyError() {
    var tmp = Error.apply(this, arguments);
    tmp.name = this.name = 'MyError'

    this.stack = tmp.stack
    this.message = tmp.message

    return this
}
    var IntermediateInheritor = function() {}
        IntermediateInheritor.prototype = Error.prototype;
    MyError.prototype = new IntermediateInheritor()

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 ...>

এই মুহুর্তে এটি করার এই একমাত্র সমস্যা (এটি আমি কিছুটা পুনরাবৃত্তি করেছি) সেগুলি

  • ছাড়া অন্য বৈশিষ্ট্য stackএবং messageঅন্তর্ভুক্ত নয় MyErrorএবং
  • স্ট্যাকট্রেসের একটি অতিরিক্ত লাইন রয়েছে যা সত্যই প্রয়োজনীয় নয়।

এই উত্তরে কৌতুকটি ব্যবহার করে ত্রুটিযুক্ত সমস্ত অগণনীয় বৈশিষ্ট্যগুলি পুনরুক্ত করে প্রথম সমস্যাটি সমাধান করা যেতে পারে: কোনও বস্তুর অগণিত উত্তরাধিকারসূত্রে প্রাপ্ত সম্পত্তি নাম পাওয়া সম্ভব? , তবে এটি <9 দ্বারা সমর্থিত নয়। দ্বিতীয় সমস্যাটি স্ট্যাক ট্রেসটিতে সেই লাইনটি ছিঁড়ে দিয়ে সমাধান করা যেতে পারে তবে নিরাপদে কীভাবে এটি করবেন তা নিশ্চিত নই (সম্ভবত কেবলমাত্র e.stack.toString এর দ্বিতীয় লাইনটি অপসারণ করা) () ??


আমি একটি মডিউল তৈরি করেছি যা ত্রুটিগুলি সহ বেশিরভাগ নিয়মিত পুরানো জাভাস্ক্রিপ্ট অবজেক্টকে প্রসারিত করতে পারে। Github.com/fresheneesz/proto
বিটি

1

স্নিপেট এটি সমস্ত দেখায়।

function add(x, y) {
      if (x && y) {
        return x + y;
      } else {
        /**
         * 
         * the error thrown will be instanceof Error class and InvalidArgsError also
         */
        throw new InvalidArgsError();
        // throw new Invalid_Args_Error(); 
      }
    }

    // Declare custom error using using Class
    class Invalid_Args_Error extends Error {
      constructor() {
        super("Invalid arguments");
        Error.captureStackTrace(this);
      }
    }

    // Declare custom error using Function
    function InvalidArgsError(message) {
      this.message = `Invalid arguments`;
      Error.captureStackTrace(this);
    }
    // does the same magic as extends keyword
    Object.setPrototypeOf(InvalidArgsError.prototype, Error.prototype);

    try{
      add(2)
    }catch(e){
      // true
      if(e instanceof Error){
        console.log(e)
      }
      // true
      if(e instanceof InvalidArgsError){
        console.log(e)
      }
    }

0

আমি একটি পদক্ষেপ ফিরে নেব এবং আপনি কেন এটি করতে চান তা বিবেচনা করব? আমি মনে করি বিন্দুটি বিভিন্ন ত্রুটিগুলি ভিন্নভাবে মোকাবেলা করা।

উদাহরণস্বরূপ, পাইথনে, আপনি ক্যাচ স্টেটমেন্টটি কেবল ধরাতে সীমাবদ্ধ করতে পারেন MyValidationErrorএবং সম্ভবত আপনি জাভাস্ক্রিপ্টে অনুরূপ কিছু করতে সক্ষম হতে চান।

catch (MyValidationError e) {
    ....
}

আপনি জাভাস্ক্রিপ্টে এটি করতে পারবেন না। এখানে কেবল একটি ক্যাচ ব্লক হতে চলেছে। ত্রুটির ধরণ নির্ধারণ করতে আপনার বিবরণ ব্যবহার করার কথা।

catch(e) { if(isMyValidationError(e)) { ... } else { // maybe rethrow? throw e; } }

আমি মনে করি পরিবর্তে কোনও প্রকার, বার্তা এবং আপনি উপযুক্ত যে কোনও বৈশিষ্ট্য সহ কোনও কাঁচা বস্তু নিক্ষেপ করব।

throw { type: "validation", message: "Invalid timestamp" }

এবং আপনি যখন ত্রুটিটি ধরেন:

catch(e) {
    if(e.type === "validation") {
         // handle error
    }
    // re-throw, or whatever else
}

1
কোনও বস্তু নিক্ষেপ করা কোনও দুর্দান্ত ধারণা নয়। আপনার কাছে কোনো আছে error.stack, মানক সাধনী দ্বারা প্রয়োগকরণ হবে এটা দিয়ে কাজ না, ইত্যাদি ইত্যাদি একটি ভাল উপায় একটি ত্রুটি ক্ষেত্রটিকেই বৈশিষ্ট্যাবলী যোগ করার জন্য হবে, যেমনvar e = new Error(); e.type = "validation"; ...
timruffles

0

কাস্টম ত্রুটি ডেকরেটার

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

দ্রষ্টব্য: এটি কেবল ভি 8 তে কাজ করবে। Error.captureStackTraceঅন্যান্য পরিবেশে কোনও সমর্থন নেই ।

নির্ধারণ করা

সাজসজ্জারটি ত্রুটি প্রকারের জন্য একটি নাম নেয় এবং একটি ক্রিয়াকলাপ দেয় যা ত্রুটি বার্তা গ্রহণ করে এবং ত্রুটির নামটি আবদ্ধ করে।

CoreError = (@message) ->

    @constructor.prototype.__proto__ = Error.prototype
    Error.captureStackTrace @, @constructor
    @name = @constructor.name

BaseError = (type) ->

    (message) -> new CoreError "#{ type }Error: #{ message }"

ব্যবহার

এখন নতুন ত্রুটির ধরণের তৈরি করা সহজ।

StorageError   = BaseError "Storage"
SignatureError = BaseError "Signature"

মজা করার জন্য, আপনি এখন এমন একটি ফাংশন সংজ্ঞায়িত করতে SignatureErrorপারেন যা খুব বেশি আর্ক দিয়ে ডাকা হয় তবে এটি ছুড়ে দেয় ।

f = -> throw SignatureError "too many args" if arguments.length

এটি বেশ ভাল পরীক্ষা করা হয়েছে এবং মনে হয় ভি 8-তে পুরোপুরি কাজ করবে, ট্রেসব্যাক, অবস্থান ইত্যাদি রক্ষণাবেক্ষণ করবে on

দ্রষ্টব্য: newকাস্টম ত্রুটি তৈরি করার সময় ব্যবহার করা optionচ্ছিক।


0

আপনি যদি ত্রুটিগুলির জন্য পারফরম্যান্সের বিষয়ে চিন্তা না করেন তবে এটি আপনার পক্ষে সবচেয়ে ছোট

Object.setPrototypeOf(MyError.prototype, Error.prototype)
function MyError(message) {
    const error = new Error(message)
    Object.setPrototypeOf(error, MyError.prototype);
    return error
}

আপনি এটি কেবল নতুন MyError (বার্তা) ছাড়াই ব্যবহার করতে পারেন

কনস্ট্রাক্টর ত্রুটি বলা হওয়ার পরে প্রোটোটাইপ পরিবর্তন করে আমাদের কলস্ট্যাক এবং বার্তা সেট করতে হবে না


0

ইএস in এর উপরে মোহসানের একটি দুর্দান্ত উত্তর রয়েছে যা নামটি সেট করে, তবে আপনি যদি টাইপস্ক্রিপ্ট ব্যবহার করছেন বা যদি আপনি ভবিষ্যতে থাকেন তবে আশাকরি পাবলিক এবং বেসরকারী শ্রেণীর ক্ষেত্রগুলির জন্য এই প্রস্তাবটি প্রস্তাব হিসাবে গত পর্যায়ে স্থান পেয়েছে এবং তৈরি করেছে ECMAScript / জাভাস্ক্রিপ্টের অংশ হিসাবে 4 ম পর্যায়ে আপনি তখন জানতে চাইতে পারেন এটি কেবলমাত্র একটু ছোট। স্টেজ 3 যেখানে ব্রাউজারগুলি বৈশিষ্ট্যগুলি প্রয়োগ করতে শুরু করে, তাই আপনার ব্রাউজারটি যদি এটি সমর্থন করে তবে নীচের কোডটি কেবল কার্যকরভাবে কাজ করবে। (নতুন এজ ব্রাউজার v81 তে পরীক্ষিত এটি ভাল কাজ করছে বলে মনে হচ্ছে)। সতর্কতা অবলম্বন করুন যদিও এই মুহুর্তে এটি একটি অস্থির বৈশিষ্ট্য এবং সতর্কতার সাথে ব্যবহার করা উচিত এবং আপনার অস্থির বৈশিষ্ট্যগুলিতে সর্বদা ব্রাউজার সমর্থন পরীক্ষা করা উচিত। এই পোস্টটি মূলত সেই ভবিষ্যত বাসিন্দাদের জন্য যখন ব্রাউজারগুলি এটি সমর্থন করতে পারে। সমর্থন চেক MDNএবং আমি ব্যবহার করতে পারি । এটি বর্তমানে ব্রাউজারের বাজার জুড়ে% 66% সমর্থন পেয়েছে যা এতটা দুর্দান্ত নয় তবে আপনি যদি এখনই এটি ব্যবহার করতে চান এবং বাবেলের মতো ট্রান্সপ্লেলার বা টাইপস্ক্রিপ্টের মতো ব্যবহার করতে অপেক্ষা করতে না চান তবে ।

class EOFError extends Error { 
  name="EOFError"
}
throw new EOFError("Oops errored");

এটি একটি নামহীন ত্রুটির সাথে তুলনা করুন যা নিক্ষেপ করলে এটির নাম লগ হয় না।

class NamelessEOFError extends Error {}
throw new NamelessEOFError("Oops errored");

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