javascript इन - ईएस 6 सिंटैक्स और बेबेल के साथ जावास्क्रिप्ट में विस्तार त्रुटि




6 Answers

करेल बिलेक के जवाब के आधार पर, मैं constructor एक छोटा बदलाव करूंगा:

class ExtendableError extends Error {
  constructor(message) {
    super(message);
    this.name = this.constructor.name;
    if (typeof Error.captureStackTrace === 'function') {
      Error.captureStackTrace(this, this.constructor);
    } else { 
      this.stack = (new Error(message)).stack; 
    }
  }
}    

// now I can extend

class MyError extends ExtendableError {}

var myerror = new MyError("ll");
console.log(myerror.message);
console.log(myerror instanceof Error);
console.log(myerror.name);
console.log(myerror.stack);

यह स्टैक में MyError प्रिंट करेगा, न कि सामान्य Error

यह स्टैक ट्रेस में त्रुटि संदेश भी जोड़ देगा - जो करेल के उदाहरण से गायब था।

यह उपलब्ध होने पर captureStackTrace भी उपयोग करेगा।

बेबेल 6 के साथ, आपको काम करने के लिए transform-builtin-extend ( npm ) की आवश्यकता है।

भाषाओं से

मैं ईएस 6 और बेबेल के साथ त्रुटि बढ़ाने की कोशिश कर रहा हूं। यह काम नहीं कर रहा है।

class MyError extends Error {
  constructor(m) {
    super(m);
  }
}

var error = new Error("ll");
var myerror = new MyError("ll");
console.log(error.message) //shows up correctly
console.log(myerror.message) //shows empty string

त्रुटि ऑब्जेक्ट को सही संदेश सेट कभी नहीं मिलता है।

बेबेल आरईपीएल में आज़माएं

अब मैंने SO पर कुछ समाधान देखे हैं ( उदाहरण के लिए यहां ), लेकिन वे सभी बहुत un-ES6-y प्रतीत होते हैं। इसे एक अच्छा, ES6 तरीके से कैसे करें? (वह बेबेल में काम कर रहा है)




अंत में इसे आराम करने के लिए। बेबेल 6 में यह स्पष्ट है कि डेवलपर्स निर्मित से विस्तार करने का समर्थन नहीं करते हैं । हालांकि यह चाल Map , Set इत्यादि जैसी चीजों में मदद नहीं करेगी , यह Error लिए काम करती है। यह महत्वपूर्ण है कि एक अपवाद फेंकने वाली भाषा के मूल विचारों में से एक कस्टम त्रुटियों को अनुमति देना है। यह दोगुना महत्वपूर्ण है क्योंकि वादे अधिक उपयोगी हो जाते हैं क्योंकि उन्हें किसी त्रुटि को अस्वीकार करने के लिए डिज़ाइन किया गया है।

दुखद सच्चाई यह है कि आपको अभी भी ES2015 में यह पुराना तरीका करने की ज़रूरत है।

बेबेल आरईपीएल में उदाहरण

कस्टम त्रुटि पैटर्न

class MyError {
  constructor(message) {
    this.name = 'MyError';
    this.message = message;
    this.stack = new Error().stack; // Optional
  }
}
MyError.prototype = Object.create(Error.prototype);

दूसरी ओर यह अनुमति देने के लिए बेबेल 6 के लिए एक प्लगइन है।

npm

अपडेट करें: (2016-09-29 तक) कुछ परीक्षणों के बाद ऐसा लगता है कि babel.io सभी आवेषणों के लिए उचित रूप से खाता नहीं है (कस्टम विस्तारित त्रुटि से विस्तारित)। लेकिन Ember.JS विस्तारित त्रुटि में अपेक्षित कार्य करता है: https://ember-twiddle.com/d88555a6f408174df0a4c8e0fd6b27ce




बेबेल 6 में नवीनतम परिवर्तनों के साथ, मुझे transform-builtin-extend अब काम नहीं कर रहा है। मैं इस मिश्रित दृष्टिकोण का उपयोग कर समाप्त हुआ:

export default class MyError {
    constructor (message) {
        this.name = this.constructor.name;
        this.message = message;
        this.stack = (new Error(message)).stack;
    }
}

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

तथा

import MyError from './MyError';

export default class MyChildError extends MyError {
    constructor (message) {
        super(message);
    }
}

नतीजतन ये सभी परीक्षण पास होते हैं:

const sut = new MyError('error message');
expect(sut.message).toBe('error message');
expect(sut).toBeInstanceOf(Error);
expect(sut).toBeInstanceOf(MyError);
expect(sut.name).toBe('MyError');
expect(typeof sut.stack).toBe('string');

const sut = new MyChildError('error message');
expect(sut.message).toBe('error message');
expect(sut).toBeInstanceOf(Error);
expect(sut).toBeInstanceOf(MyError);
expect(sut).toBeInstanceOf(MyChildError);
expect(sut.name).toBe('MyChildError');
expect(typeof sut.stack).toBe('string');



Quoting

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

इस के लिए कोई ज़रूरत नहीं है this.stack = (new Error()).stack; super() कॉल के लिए चाल धन्यवाद।

हालांकि उपर्युक्त कोड स्टैक ट्रेस आउटपुट नहीं कर सकते हैं जब तक यह this.stack = (new Error()).stack; या Error.captureStackTrace(this, this.constructor.name); Babel में बुलाया जाता है। आईएमओ, यह शायद यहां एक मुद्दा है।

असल में, इस कोड स्निपेट के साथ Chrome console और Node.js v4.2.1 तहत स्टैक ट्रेस आउटपुट हो सकता है।

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

var myerr = new MyError("test");
console.log(myerr.stack);
console.log(myerr);

Chrome console का आउटपुट।

MyError: test
    at MyError (<anonymous>:3:28)
    at <anonymous>:12:19
    at Object.InjectedScript._evaluateOn (<anonymous>:875:140)
    at Object.InjectedScript._evaluateAndWrap (<anonymous>:808:34)
    at Object.InjectedScript.evaluate (<anonymous>:664:21)

Node.js आउटपुट

MyError: test
    at MyError (/home/bsadmin/test/test.js:5:8)
    at Object.<anonymous> (/home/bsadmin/test/test.js:11:13)
    at Module._compile (module.js:435:26)
    at Object.Module._extensions..js (module.js:442:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Function.Module.runMain (module.js:467:10)
    at startup (node.js:134:18)
    at node.js:961:3



यह देखते हुए स्वीकार्य उत्तर अब काम नहीं करता है आप हमेशा एक कारखाने का उपयोग वैकल्पिक ( repl ) के रूप में कर सकते हैं:

function ErrorFactory(name) {
   return class AppError extends Error {
    constructor(message) {
      super(message);
      this.name = name;
      this.message = message; 
      if (typeof Error.captureStackTrace === 'function') {
        Error.captureStackTrace(this, this.constructor);
      } else { 
        this.stack = (new Error(message)).stack; 
      }
    }
  }     
}

// now I can extend
const MyError = ErrorFactory("MyError");


var myerror = new MyError("ll");
console.log(myerror.message);
console.log(myerror instanceof Error);
console.log(myerror.name);
console.log(myerror.stack);




बेबेल का उपयोग नहीं कर रहा है, लेकिन सादे ES6 में, निम्नलिखित मेरे लिए ठीक काम करता है:

class CustomError extends Error {
    constructor(...args) {
        super(...args);
        this.name = this.constructor.name;
    }
}

आरईपीएल से परीक्षण:

> const ce = new CustomError('foobar');
> ce.name
'CustomError'
> ce.message
'foobar'
> ce instanceof CustomError
true
> ce.stack
'CustomError: foobar\n    at CustomError (repl:3:1)\n ...'

जैसा कि आप देख सकते हैं, स्टैक में त्रुटि नाम और संदेश दोनों शामिल हैं। मुझे यकीन नहीं है कि मुझे कुछ याद आ रहा है, लेकिन अन्य सभी उत्तरों चीजों को अधिक जटिल बनाते हैं।




Related