जावास्क्रिप्ट में त्रुटि को बढ़ाने का एक अच्छा तरीका क्या है?


367

मैं अपने जेएस कोड में कुछ चीजें फेंकना चाहता हूं और मैं चाहता हूं कि उन्हें इंस्टाफॉरेक्ट एरर किया जाए, लेकिन मैं यह भी चाहता हूं कि वे कुछ और हों।

पायथन में, आम तौर पर, एक अपवाद को उप-वर्ग में बदल देगा।

जेएस में क्या करना उचित है?

जवाबों:


217

केवल मानक फ़ील्ड त्रुटि ऑब्जेक्ट के पास messageगुण है। (देखें MDN , या ECMAScript भाषा विशिष्टता, खंड 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";
किबरनेटिको

11
मैं MyError.prototype.constructor = MyErrorभी जोड़ दूंगा।
भरत खत्री

3
ES6 Error.call में (यह, संदेश); शुरू करना चाहिए this, है ना?
4esn0k

4
MyError.prototyp = Object.create (Error.prototype);
रॉबिन

170

ES6 में:

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

स्रोत


53
इस बात का उल्लेख करते हुए कि अगर आप ES6 सुविधाओं का उपयोग किसी ट्रांसपिलर के माध्यम से नहीं कर रहे हैं, जैसे कि बाबेल, क्योंकि उपवर्गों को एक वर्ग का विस्तार करना चाहिए।
बजकर 01 मिनट पर आहीदन

6
यदि आप कोलाहल का उपयोग कर रहे हैं और नोड> 5 पर हैं। तो आपको es2015 पूर्व निर्धारित का उपयोग नहीं करना चाहिए, लेकिन npmjs.com/package/babel-preset-node5 आपको मूल es6 का उपयोग करने की अनुमति देगा और अधिक विस्तार
Ace

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;
    }
  • वैकल्पिक: Classtrophobic ढांचे का उपयोग करें

स्पष्टीकरण:

ES6 और बैबल का उपयोग करके त्रुटि वर्ग का विस्तार क्यों एक समस्या है?

क्योंकि CustomError की एक उदाहरण अब इस तरह से मान्यता प्राप्त नहीं है।

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

वास्तव में, कोलाहल के आधिकारिक दस्तावेज से, आप किसी भी अंतर्निहित जावास्क्रिप्ट वर्गों विस्तार नहीं कर सकते जैसे Date, Array, DOMया Error

समस्या यहाँ वर्णित है:

अन्य SO उत्तर के बारे में क्या?

दिए गए सभी उत्तर समस्या को ठीक करते हैं 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 सिंटैक्स के साथ जावास्क्रिप्ट में फैली त्रुटि' बैबल विशिष्ट है, आपका ईएस 5 समाधान उपयोग करता है constऔर यह कस्टम तर्कों को संभाल नहीं पाता है।
इंडोलरिंग

बहुत पूरा जवाब।
डेनियल ऑरलैंडो

यह वास्तव में सबसे व्यापक समाधान प्रदान करता है और बताता है कि विभिन्न टुकड़े क्यों आवश्यक हैं। बहुत बहुत धन्यवाद JBE!
एंड्रयूसपॉव जूल

इससे मुझे "त्रुटि" से विरासत में मिली समस्या को सुलझाने में मदद मिली। यह दो घंटे का दुःस्वप्न था!
इयूलियन पिंजारू

2
ध्यान देने योग्य बात यह है कि console.log(new CustomError('test') instanceof CustomError);// falseलेखन के समय यह मुद्दा सही था लेकिन अब इसे सुलझा लिया गया है। वास्तव में उत्तर में जुड़ी समस्या को हल कर दिया गया है और हम यहां सही व्यवहार का परीक्षण कर सकते हैं और आरईपीएल में कोड चिपकाकर और यह देख सकते हैं कि कैसे सही प्रोटोटाइप श्रृंखला के साथ त्वरित करने के लिए इसे सही ढंग से ट्रांसप्लेंड किया जाता है।
नोबिता

44

संपादित करें: कृपया टिप्पणियों को पढ़ें। यह पता चला है कि यह केवल V8 (Chrome / Node.JS) में अच्छा काम करता है। मेरा इरादा क्रॉस-ब्राउज़र समाधान प्रदान करना था, जो सभी ब्राउज़रों में काम करेगा, और स्टैक ट्रेस प्रदान करेगा जहां समर्थन है।

संपादित करें: मैंने अधिक संपादन के लिए अनुमति देने के लिए यह सामुदायिक विकी बनाया।

V8 (Chrome / Node.JS) के लिए समाधान, फ़ायरफ़ॉक्स में काम करता है, और IE में अधिकतर सही ढंग से कार्य करने के लिए संशोधित किया जा सकता है। (पोस्ट का अंत देखें)

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

वह कार्य फ़ंक्शन लागू नहीं करता है, क्योंकि फ़ंक्शंस पहले बनाए जाते हैं, चाहे कोई भी ऑर्डर हो। इस प्रकार, आप समस्या के बिना फ़ंक्शन को फ़ाइल के अंत में स्थानांतरित कर सकते हैं।

ब्राउज़र संगतता

फ़ायरफ़ॉक्स और क्रोम (और Node.JS) में काम करता है और सभी वादों को पूरा करता है।

इंटरनेट एक्सप्लोरर निम्नलिखित में विफल रहता है

  • त्रुटियों के 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जब तक आप इससे पहले कि आप कुछ समय के निम्नलिखित चलानेthrow UserError

    UserError.prototype = Error.prototype

16
मुझे नहीं लगता कि फ़ायरफ़ॉक्स वास्तव में कैप्चरस्टैक है। यह एक V8 विस्तार है और मेरे लिए फ़ायरफ़ॉक्स में अपरिभाषित है, और न ही मैं वेब पर फ़ायरफ़ॉक्स को इसका समर्थन करने के लिए कोई संदर्भ पा सकता हूं। (धन्यवाद हालांकि!)
ज्योफ

5
Error.call(this)वास्तव में कुछ भी नहीं कर रहा है क्योंकि यह संशोधित करने के बजाय एक त्रुटि देता हैthis
किबरनेटिको

1
Node.js के लिए महान काम करता है
रुडोल्फ मीज़रिंग

1
UserError.prototype = Error.prototypeभ्रामक है। यह वंशानुक्रम नहीं करता है, यह उन्हें एक ही वर्ग बनाता है ।
१०:१०

1
मेरा मानना Object.setPrototypeOf(this.constructor.prototype, Error.prototype)है कि this.constructor.prototype.__proto__ = Error.prototypeकम से कम वर्तमान ब्राउज़रों के लिए पसंद किया जाता है।
क्रिस

29

करने के लिए बॉयलरप्लेट से बचने त्रुटि के हर विभिन्न प्रकार के लिए, मैं एक में समाधान में से कुछ का ज्ञान संयुक्त  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;?
पीटर Tseng

@PeterTseng चूंकि nameपहले से ही प्रोटोटाइप पर सेट है, इसलिए यह अब आवश्यक नहीं है। मैंने उसे हटा दिया। धन्यवाद!
रूबेन वेरबर्ग

27

में 2018 , मुझे लगता है कि यह सबसे अच्छा तरीका है; कि IE9 + और आधुनिक ब्राउज़रों का समर्थन करता है।

अद्यतन : इस परीक्षण और विभिन्न कार्यान्वयन पर तुलना के लिए रेपो देखें ।

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 में मुझे लगता है कि वास्तव में त्रुटियों का विस्तार करने का एक बेहतर तरीका है, हालांकि मुझे अभी भी पता चल रहा है कि बैबेल के साथ मिलकर इसका उपयोग कैसे किया जाए: github.com/loganfsmyth/babel-plugin-transform-builtin-extil/…
मैट ब्राउन

CustomError.prototype = Object.create(Error.prototype)प्रोटोटाइप भी बदल रहा है। आपको इसे बदलना होगा क्योंकि ES5 में कोई अंतर्निहित विस्तार / इनहेरिट लॉजिक नहीं है। मुझे यकीन है कि आप जिस बबल प्लग इन का उल्लेख करते हैं वह इसी तरह की चीजें करता है।
ओनुर येल्ड्रिअम

1
मैंने यह प्रदर्शित करने के लिए एक जिस्ट का निर्माण किया कि Object.setPrototypeOfइसका उपयोग करने का मतलब यहाँ क्यों नहीं है, कम से कम उस तरीके से नहीं जो आप इसका उपयोग कर रहे हैं: gist.github.com/mbrowne/4af54767dc3d529648f5a8aa11dn34348 । शायद आप लिखने का मतलब है Object.setPrototypeOf(CustomError.prototype, Error.prototype)- यह थोड़ा और अधिक समझ में आता है (हालांकि अभी भी बस सेटिंग पर कोई लाभ नहीं दे रहा है CustomError.prototype)।
मैट ब्राउन ने

19

पूर्णता के लिए - सिर्फ इसलिए कि पिछले उत्तरों में से किसी ने भी इस पद्धति का उल्लेख नहीं किया है - यदि आप Node.js के साथ काम कर रहे हैं और ब्राउज़र संगतता के बारे में परवाह नहीं है, तो वांछित प्रभाव बिल्ट इन के साथ हासिल करना बहुत आसान है inheritsके utilमॉड्यूल ( सरकारी डॉक्स यहाँ )।

उदाहरण के लिए, मान लें कि आप एक कस्टम त्रुटि वर्ग बनाना चाहते हैं जो पहले तर्क के रूप में एक त्रुटि कोड लेता है और दूसरा त्रुटि संदेश के रूप में:

फ़ाइल custom-error.js :

'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

क्रिसेंट फ्रेश का अत्यधिक मत वाला उत्तर भ्रामक है। यद्यपि उसकी चेतावनियां अमान्य हैं, लेकिन अन्य सीमाएँ हैं जिन्हें वह संबोधित नहीं करता है।

सबसे पहले, क्रिसेंट के "कैविट्स:" पैराग्राफ में तर्क का कोई मतलब नहीं है। व्याख्या का अर्थ है कि कोडिंग "अगर (त्रुटि इंस्ट्रूमेंट मायएयर) का एक गुच्छा ..." किसी तरह से कई कैच स्टेटमेंट्स की तुलना में बोझ या क्रिया है। एक ही कैच ब्लॉक में मल्टीपल इंस्टोफ स्टेटमेंट उतने ही संक्षिप्त होते हैं जितने कि कई कैच स्टेटमेंट- बिना किसी ट्रिक्स के क्लीन एंड कॉन्साइज कोड। यह जावा के महान फेंकने योग्य-उपप्रकार-विशिष्ट त्रुटि हैंडलिंग का अनुकरण करने का एक शानदार तरीका है।

WRT "उपवर्ग की संदेश संपत्ति दिखाई नहीं देती है" सेट हो जाता है, यदि आप ठीक से निर्मित त्रुटिक्लास का उपयोग करते हैं तो यह मामला नहीं है। अपनी खुद की ErrorX Error को उपवर्ग बनाने के लिए, बस "var MyError =" के साथ शुरू होने वाले कोड ब्लॉक को कॉपी करें, एक शब्द "MyError" को "ErrorX" में बदल दें। (यदि आप अपने उपवर्ग में कस्टम तरीके जोड़ना चाहते हैं, तो नमूना पाठ का पालन करें)।

जावास्क्रिप्ट त्रुटि उपवर्ग की वास्तविक और महत्वपूर्ण सीमा यह है कि जावास्क्रिप्ट कार्यान्वयन या डिबगर्स के लिए जो ट्रैक करते हैं और स्टैक ट्रेस और स्थान-तत्काल पर रिपोर्ट करते हैं, जैसे कि फ़ायरफ़ॉक्स, आपकी खुद की त्रुटि उपवर्ग कार्यान्वयन में एक स्थान को तत्काल बिंदु के रूप में दर्ज किया जाएगा। वर्ग, जबकि यदि आपने प्रत्यक्ष त्रुटि का उपयोग किया है, तो यह वह स्थान होगा जहां आपने "नई त्रुटि (...)" चलाया था। IE उपयोगकर्ता शायद कभी नोटिस नहीं करेंगे, लेकिन FF पर फायर बग के उपयोगकर्ता इन त्रुटियों के साथ रिपोर्ट किए गए बेकार फ़ाइल नाम और लाइन नंबर मान देखेंगे, और वास्तविक तात्कालिक स्थान को खोजने के लिए तत्व # 1 को स्टैक ट्रेस पर ड्रिल करना होगा।


क्या मुझे यह सही लगा - कि यदि आप सीधे उप-लिंक नहीं करते हैं और नई त्रुटि (...) का उपयोग करते हैं, तो फ़ाइल नाम और लाइन को ठीक से रिपोर्ट किया जा रहा है? और आप मूल रूप से कहते हैं कि अभ्यास पर (असली और सिर्फ सेक्सी या सजावटी थोड़े की नहीं) उपवर्गों को तोड़कर, कोई मतलब नहीं है?
जरजो

6
यह उत्तर कुछ ऐसा Crescent Fresh'sहै जिसे हटा दिया गया है!
पीटर

क्या अभी भी यही मामला है? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… लाइन नंबर 2 नहीं है जहां नया कहा गया था
मुहम्मद उमर

13

इस समाधान के बारे में कैसे?

इसके बजाय अपने कस्टम त्रुटि का उपयोग कर फेंक:

throw new MyError("Oops!");

आप त्रुटि ऑब्जेक्ट (एक डेकोरेटर की तरह) को लपेटेंगे:

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

यह सुनिश्चित करता है कि सभी विशेषताएँ सही हैं, जैसे कि स्टैक, फ़ाइलनाम लाइननंबर, वगैरह।

इसके बाद आपको केवल या तो विशेषताओं पर कॉपी करना है, या उनके लिए गेटर्स को परिभाषित करना है। यहाँ गेटर्स (IE9) का उपयोग करके एक उदाहरण दिया गया है:

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
मैंने इस समाधान को एक npm
JoWie

अविश्वसनीय रूप से सुरुचिपूर्ण समाधान, साझा करने के लिए धन्यवाद! एक भिन्नता: new MyErr (arg1, arg2, new Error())और MyErr कंस्ट्रक्टर में हम Object.assignअंतिम आर्ग के गुण निर्दिष्ट करने के लिए उपयोग करते हैंthis
पीयूष कुशवाहा

यह मुझे पंसद है। आप इनहेरिटेंस के बजाय इनकैप्सुलेशन का उपयोग करके एक सीमा को बायपास करते हैं।
जेनी ओ'रेली

13

जैसा कि कुछ लोगों ने कहा है, यह ES6 के साथ काफी आसान है:

class CustomError extends Error { }

इसलिए मैंने कोशिश की कि मेरे ऐप के भीतर, (कोणीय, टाइपस्क्रिप्ट) और यह सिर्फ काम नहीं करे। कुछ समय बाद मैंने पाया है कि समस्या टाइपस्क्रिप्ट: O से आ रही है

Https://github.com/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

मेरा समाधान प्रदान किए गए अन्य उत्तरों की तुलना में अधिक सरल है और इसमें डाउनसाइड नहीं है।

यह त्रुटि प्रोटोटाइप श्रृंखला और त्रुटि के सभी गुणों को उनके विशिष्ट ज्ञान की आवश्यकता के बिना सुरक्षित रखता है। यह क्रोम, फ़ायरफ़ॉक्स, नोड और IE11 में परीक्षण किया गया है।

केवल सीमा कॉल स्टैक के शीर्ष पर एक अतिरिक्त प्रविष्टि है। लेकिन वह आसानी से नजरअंदाज कर दिया जाता है।

यहां दो कस्टम मापदंडों के साथ एक उदाहरण दिया गया है:

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 कक्षाओं का उपयोग करना भी अच्छी तरह से काम करता है)। त्रुटियाँ क्रोमियम DevTools में अन्य उत्तरों की तुलना में बहुत अधिक अच्छी तरह से प्रदर्शित होती हैं।
बेन गबलर

नोट: यदि आप टाइपस्क्रिप्ट के साथ इस समाधान का उपयोग कर रहे हैं, तो आपको 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';

जब सब कहा और किया जाता है, तो आप अपने नए अपवाद को फेंक देते हैं और यह इस तरह दिखता है (मैंने क्रोम डिवाइसेस में lazily यह कोशिश की):

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 सेंट:

दूसरा जवाब क्यों?

a) क्योंकि Error.stackसंपत्ति तक पहुँचना (कुछ उत्तरों में) एक बड़ा प्रदर्शन जुर्माना है।

b) क्योंकि यह केवल एक लाइन है।

c) क्योंकि https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error पर समाधान स्टैक जानकारी को संरक्षित करने के लिए नहीं लगता है।

//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__श्रृंखला में नए त्रुटि गुण (.stack) भी डालता है ।

स्पष्ट समस्या:

आपके पास उपयोगी स्टैक जानकारी के साथ MyError के एक से अधिक उदाहरण नहीं हो सकते हैं।

यदि आप पूरी तरह से नहीं समझते हैं कि इस समाधान का उपयोग न करें this.__proto__.__proto__=


2

चूंकि जावास्क्रिप्ट अपवाद उप-वर्ग के लिए कठिन हैं, इसलिए मैं उप-वर्ग नहीं करता। मैं बस एक नया अपवाद वर्ग बनाता हूं और इसके अंदर एक त्रुटि का उपयोग करता हूं। मैं Error.name प्रॉपर्टी को बदलता हूं ताकि यह कंसोल पर मेरे कस्टम अपवाद जैसा लगे:

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 

कैविएट: स्टैक ट्रेस सही नहीं है, क्योंकि यह आपको नई त्रुटि बनाने के लिए लाएगा, जहां आप फेंकते हैं। Chrome पर यह कोई बड़ी बात नहीं है क्योंकि यह आपको कंसोल में सीधे पूर्ण स्टैक ट्रेस प्रदान करता है। उदाहरण के लिए, यह फ़ायरफ़ॉक्स पर अधिक समस्याग्रस्त है।


यह मामले में विफल रहता हैm = new InvalidInputError(); dontThrowMeYet(m);
एरिक

@ मैं सहमत हूँ, लेकिन यह एक बहुत छोटी सीमा की तरह लगता है। मुझे समय से पहले एक अपवाद वस्तु को तुरंत हटाने की आवश्यकता नहीं है (ऊपर मेरे कोड नमूने की तरह मेटा-प्रोग्रामिंग उपयोगों को छोड़कर)। क्या यह वास्तव में आपके लिए एक मुद्दा है?
जोनाथन बेन

हां, व्यवहार समान लगता है, इसलिए मैं अपना उत्तर बदलूंगा। मैं स्टैक ट्रेस से 100% संतुष्ट नहीं हूँ, जो आपको फ़ायरफ़ॉक्स और क्रोम पर "var error" लाइन पर लाता है
जोनाथन बेन्न

1
@JonathanBenn मैं पार्टी के लिए देर से असली हूं, इसलिए शायद आप इसे पहले ही उठा चुके हैं। जब मैं अतुल्यकालिक प्रोग्रामिंग और वादों का उपयोग करता हूं, तो मैं अक्सर एक अपवाद वस्तु को तुरंत हटा देता हूं। @ एरिक के नाम के बाद, मैं अक्सर उपयोग m = new ...तो Promise.reject(m)। यह कोई आवश्यकता नहीं है, लेकिन कोड को पढ़ना आसान है।
बाल्डेगल

1
@JonathanBenn: (वह वह) अक्टूबर 14 में, आपको लगता है कि एक अपवाद वस्तु को फेंकने से पहले यह दुर्लभ होगा। मैंने एक बार ऐसा करने का उदाहरण दिया। मैं यह नहीं कहूंगा कि यह सामान्य है, लेकिन जब मैं चाहता हूं, तो यह करना आसान है। और, मेरा कोड अधिक पठनीय है क्योंकि तात्कालिकता सभी एक पंक्ति पर है और सभी दूसरे पर अस्वीकार कर रहे हैं। मुझे आशा है कि यह करता है!
बाल्डाग्ले

2

जैसा कि मोहसिन के जवाब में बताया गया है, ईएस 6 में कक्षाओं का उपयोग करके त्रुटियों का विस्तार करना संभव है। यह बहुत आसान है और उनका व्यवहार मूल त्रुटियों के साथ अधिक सुसंगत है ... लेकिन दुर्भाग्यवश ब्राउज़र में इस का उपयोग करना आसान नहीं है यदि आपको पूर्व-ईएस 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()ES6 का समर्थन करने वाले ब्राउज़रों के लिए गतिशील रूप से (जैसे AJAX या के माध्यम से ) एक अलग स्क्रिप्ट लोड करना होगा । एक और जटिलता यह है कि eval()सभी वातावरण (सामग्री सुरक्षा नीतियों के कारण) में समर्थित नहीं है, जो आपकी परियोजना के लिए एक विचार हो सकता है या नहीं भी हो सकता है।

तो अब के लिए, या तो ऊपर का पहला तरीका या Errorसीधे सीधे इसे बढ़ाने की कोशिश किए बिना उपयोग करना सबसे अच्छा लगता है जो व्यावहारिक रूप से उस कोड के लिए किया जा सकता है जिसे गैर-ईएस 6 ब्राउज़रों का समर्थन करने की आवश्यकता होती है।

एक अन्य दृष्टिकोण है जो कुछ लोग विचार करना चाह सकते हैं, जो 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
BT

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

कस्टम त्रुटि डेकोरेटर

यह जॉर्ज बेली के उत्तर पर आधारित है , लेकिन मूल विचार का विस्तार और सरलीकरण करता है। यह कॉफीस्क्रिप्ट में लिखा गया है, लेकिन जावास्क्रिप्ट में बदलना आसान है। विचार बेली की कस्टम त्रुटि को एक डेकोरेटर के साथ बढ़ाता है जो इसे लपेटता है, जिससे आप आसानी से नई कस्टम त्रुटियां बना सकते हैं।

नोट: यह केवल V8 में काम करेगा। 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

यह बहुत अच्छी तरह से परीक्षण किया गया है और V8 पर पूरी तरह से काम करता है, ट्रेसबैक, स्थिति आदि को मुख्य रूप से देखता है।

नोट: newकस्टम त्रुटि का निर्माण करते समय उपयोग वैकल्पिक है।


0

यदि आप त्रुटियों के लिए प्रदर्शन के बारे में परवाह नहीं करते हैं तो यह सबसे छोटा है जो आप कर सकते हैं

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

आप इसे बिना नए MyError (संदेश) के उपयोग कर सकते हैं

कंस्ट्रक्टर एरर कहे जाने के बाद प्रोटोटाइप को बदलकर हमें कॉलस्टैक और मैसेज सेट करने की जरूरत नहीं है


0

मोहसिन के पास ईएस 6 में एक बड़ा जवाब है जो नाम सेट करता है, लेकिन यदि आप टाइपस्क्रिप्ट का उपयोग कर रहे हैं या यदि आप भविष्य में रह रहे हैं जहां उम्मीद है कि सार्वजनिक और निजी वर्ग के क्षेत्रों के लिए यह प्रस्ताव पिछले चरण 3 को एक प्रस्ताव के रूप में स्थानांतरित कर दिया है और इसे बनाया है ECMAScript / जावास्क्रिप्ट के भाग के रूप में चरण 4 में तब आप यह जानना चाहते होंगे कि यह अभी थोड़ा छोटा है। स्टेज 3 वह जगह है जहाँ ब्राउज़र सुविधाओं को लागू करना शुरू करते हैं, इसलिए यदि आपका ब्राउज़र इसे समर्थन करता है तो नीचे दिया गया कोड काम कर सकता है। (नए एज ब्राउज़र v81 में परीक्षण किया गया कि यह ठीक काम करता है)। सावधान रहें हालांकि यह इस समय एक अस्थिर विशेषता है और इसका सावधानी से उपयोग किया जाना चाहिए और आपको हमेशा अस्थिर सुविधाओं पर ब्राउज़र समर्थन की जांच करनी चाहिए। यह पोस्ट मुख्य रूप से उन भविष्य के निवासियों के लिए है जब ब्राउज़र इस का समर्थन कर सकते हैं। समर्थन की जाँच करने के लिए MDN की जाँच करेंऔर क्या मैं उपयोग कर सकता हूँ ? यह वर्तमान में ब्राउज़र बाजार जो वहाँ लेकिन ऐसा नहीं है कि महान इसलिए यदि आप वास्तव में अब इसका उपयोग करना चाहते हैं और या तो इंतजार की तरह एक transpiler उपयोग करने के लिए नहीं चाहते हो रही है भर में 66% समर्थन मिला है कोलाहल या की तरह कुछ टाइपप्रति

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

इसकी तुलना एक ऐसी त्रुटि से करें, जिसे जब फेंका जाएगा तो यह नाम नहीं होगा।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.