javascript জাভাস্ক্রিপ্ট কাস্টম ব্যতিক্রম



exception-handling (11)

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

আমি কি জাভাস্ক্রিপ্টে ব্যবহারকারী-সংজ্ঞায়িত ব্যতিক্রমগুলির জন্য কাস্টম প্রকার সংজ্ঞায়িত করতে পারি? যদি আমি পারি, কিভাবে করবো?


function MyError(message) {
 this.message = message;
}

MyError.prototype = new Error;

এটি ব্যবহার করার জন্য অনুমতি দেয় ..

try {
  something();
 } catch(e) {
  if(e instanceof MyError)
   doSomethingElse();
  else if(e instanceof Error)
   andNowForSomethingCompletelyDifferent();
}

আপনি নিজের মতামত এবং তাদের হ্যান্ডলিং বাস্তবায়ন করতে পারেন যেমন এখানে:

// define exceptions "classes" 
function NotNumberException() {}
function NotPositiveNumberException() {}

// try some code
try {
    // some function/code that can throw
    if (isNaN(value))
        throw new NotNumberException();
    else
    if (value < 0)
        throw new NotPositiveNumberException();
}
catch (e) {
    if (e instanceof NotNumberException) {
        alert("not a number");
    }
    else
    if (e instanceof NotPositiveNumberException) {
        alert("not a positive number");
    }
}

টাইপ করা ব্যতিক্রম ধরার জন্য আরেকটি সিনট্যাক্স রয়েছে, যদিও এটি প্রতিটি ব্রাউজারে কাজ করবে না (উদাহরণস্বরূপ IE তে নয়):

// define exceptions "classes" 
function NotNumberException() {}
function NotPositiveNumberException() {}

// try some code
try {
    // some function/code that can throw
    if (isNaN(value))
        throw new NotNumberException();
    else
    if (value < 0)
        throw new NotPositiveNumberException();
}
catch (e if e instanceof NotNumberException) {
    alert("not a number");
}
catch (e if e instanceof NotPositiveNumberException) {
    alert("not a positive number");
}

MDN এই উদাহরণ দেখুন।

যদি আপনি একাধিক ত্রুটি সংজ্ঞায়িত করতে চান ( here কোড পরীক্ষা here !):

function createErrorType(name, initFunction) {
    function E(message) {
        this.message = message;
        if (Error.captureStackTrace)
            Error.captureStackTrace(this, this.constructor);
        else
            this.stack = (new Error()).stack;
        initFunction && initFunction.apply(this, arguments);
    }
    E.prototype = Object.create(Error.prototype);
    E.prototype.name = name;
    E.prototype.constructor = E;
    return E;
}
var InvalidStateError = createErrorType(
    'InvalidStateError',
    function (invalidState, acceptedStates) {
        this.message = 'The state ' + invalidState + ' is invalid. Expected ' + acceptedStates + '.';
    });

var error = new InvalidStateError('foo', 'bar or baz');
function assert(condition) { if (!condition) throw new Error(); }
assert(error.message);
assert(error instanceof InvalidStateError);  
assert(error instanceof Error); 
assert(error.name == 'InvalidStateError');
assert(error.stack);
error.message;

কোডটি বেশিরভাগ থেকে কপি করা হয়: জাভাস্ক্রিপ্টে ত্রুটি প্রসারিত করার জন্য একটি ভাল উপায় কী?


এখানে আপনি কীভাবে স্থানীয় Error আচরণের সাথে একেবারে সাদৃশ্যযুক্ত কাস্টম ত্রুটিগুলি তৈরি করতে পারেন। এই কৌশলটি এখন শুধুমাত্র ক্রোম এবং node.js এ কাজ করে । আপনি এটি কি না বুঝতে না যদি আমি এটা ব্যবহার করার সুপারিশ করবে না

Error.createCustromConstructor = (function() {

    function define(obj, prop, value) {
        Object.defineProperty(obj, prop, {
            value: value,
            configurable: true,
            enumerable: false,
            writable: true
        });
    }

    return function(name, init, proto) {
        var CustomError;
        proto = proto || {};
        function build(message) {
            var self = this instanceof CustomError
                ? this
                : Object.create(CustomError.prototype);
            Error.apply(self, arguments);
            Error.captureStackTrace(self, CustomError);
            if (message != undefined) {
                define(self, 'message', String(message));
            }
            define(self, 'arguments', undefined);
            define(self, 'type', undefined);
            if (typeof init == 'function') {
                init.apply(self, arguments);
            }
            return self;
        }
        eval('CustomError = function ' + name + '() {' +
            'return build.apply(this, arguments); }');
        CustomError.prototype = Object.create(Error.prototype);
        define(CustomError.prototype, 'constructor', CustomError);
        for (var key in proto) {
            define(CustomError.prototype, key, proto[key]);
        }
        Object.defineProperty(CustomError.prototype, 'name', { value: name });
        return CustomError;
    }

})();

একটি reasult হিসাবে আমরা পেতে

/**
 * name   The name of the constructor name
 * init   User-defined initialization function
 * proto  It's enumerable members will be added to 
 *        prototype of created constructor
 **/
Error.createCustromConstructor = function(name, init, proto)

তারপর আপনি এটি ব্যবহার করতে পারেন:

var NotImplementedError = Error.createCustromConstructor('NotImplementedError');

এবং আপনি NotImplementedError Error হিসাবে NotImplementedError Error ব্যবহার করুন:

throw new NotImplementedError();
var err = new NotImplementedError();
var err = NotImplementedError('Not yet...');

এবং এটা প্রত্যাশিত আচরণ করা হবে:

err instanceof NotImplementedError               // -> true
err instanceof Error                             // -> true
NotImplementedError.prototype.isPrototypeOf(err) // -> true
Error.prototype.isPrototypeOf(err)               // -> true
err.constructor.name                             // -> NotImplementedError
err.name                                         // -> NotImplementedError
err.message                                      // -> Not yet...
err.toString()                                   // -> NotImplementedError: Not yet...
err.stack                                        // -> works fine!

দ্রষ্টব্য, error.stack কাজ করে এবং NotImplementedError কন্সট্রকটর কল অন্তর্ভুক্ত করবে না (ধন্যবাদ v8 এর Error.captureStackTrace() . Error.captureStackTrace() )।

বিঃদ্রঃ. কুৎসিত eval() । এটি ব্যবহার করা হয় একমাত্র কারণ সঠিক err.constructor.name পেতে। আপনি এটি প্রয়োজন না হলে, আপনি কিছুটা সহজ করতে পারেন।


ওয়েব WebReference থেকে:

throw { 
  name:        "System Error", 
  level:       "Show Stopper", 
  message:     "Error detected. Please contact the system administrator.", 
  htmlMessage: "Error detected. Please contact the <a href=\"mailto:[email protected]\">system administrator</a>.",
  toString:    function(){return this.name + ": " + this.message;} 
}; 

সংক্ষেপে:

বিকল্প 1: babel-plugin-transform-builtin-extend

বিকল্প 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) {
      const 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 এবং Babel ব্যবহার করে ত্রুটি শ্রেণী প্রসারিত করা একটি সমস্যা?

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

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 উত্তর সম্পর্কে কি?

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

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

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

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

আমি প্রায়ই প্রোটোটাইল উত্তরাধিকার সঙ্গে একটি পদ্ধতির ব্যবহার। ওভার্রাইটিং toString() আপনাকে সুবিধা প্রদান করে যা ফায়ারবগের মতো সরঞ্জামগুলি [object Object] পরিবর্তে প্রকৃত তথ্য লগ ইন করবে না।

ব্যতিক্রম ধরনের নির্ধারণ করতে instanceof ব্যবহার করুন।

main.js

// just an exemplary namespace
var ns = ns || {};

// include JavaScript of the following
// source files here (e.g. by concatenation)

var someId = 42;
throw new ns.DuplicateIdException('Another item with ID ' +
    someId + ' has been created');
// Firebug console:
// uncaught exception: [Duplicate ID] Another item with ID 42 has been created

Exception.js

ns.Exception = function() {
}

/**
 * Form a string of relevant information.
 *
 * When providing this method, tools like Firebug show the returned 
 * string instead of [object Object] for uncaught exceptions.
 *
 * @return {String} information about the exception
 */
ns.Exception.prototype.toString = function() {
    var name = this.name || 'unknown';
    var message = this.message || 'no description';
    return '[' + name + '] ' + message;
};

DuplicateIdException.js

ns.DuplicateIdException = function(message) {
    this.name = 'Duplicate ID';
    this.message = message;
};

ns.DuplicateIdException.prototype = new ns.Exception();

ES6

নতুন ক্লাস এবং কীওয়ার্ড প্রসারিত করুন এটি এখন অনেক সহজ:

class CustomError extends Error {
  constructor(message) {
    super(message);
    //something
  }
}

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

function InvalidArgumentException(message) {
    this.message = message;
    // Use V8's native method if available, otherwise fallback
    if ("captureStackTrace" in Error)
        Error.captureStackTrace(this, InvalidArgumentException);
    else
        this.stack = (new Error()).stack;
}

InvalidArgumentException.prototype = Object.create(Error.prototype);
InvalidArgumentException.prototype.name = "InvalidArgumentException";
InvalidArgumentException.prototype.constructor = InvalidArgumentException;

এটি মূলত ফায়ারফক্স এবং অন্যান্য ব্রাউজারগুলিতে স্ট্যাক ট্রেসগুলির উন্নতির উপরে disfated কোন disfated পোস্টের সরলীকৃত সংস্করণ। তিনি পোস্ট করেছেন যে একই পরীক্ষা সন্তুষ্ট:

ব্যবহার:

throw new InvalidArgumentException();
var err = new InvalidArgumentException("Not yet...");

এবং এটা প্রত্যাশিত আচরণ করা হবে:

err instanceof InvalidArgumentException          // -> true
err instanceof Error                             // -> true
InvalidArgumentException.prototype.isPrototypeOf(err) // -> true
Error.prototype.isPrototypeOf(err)               // -> true
err.constructor.name                             // -> InvalidArgumentException
err.name                                         // -> InvalidArgumentException
err.message                                      // -> Not yet...
err.toString()                                   // -> InvalidArgumentException: Not yet...
err.stack                                        // -> works fine!

throw বিবৃতি ব্যবহার করুন।

জাভাস্ক্রিপ্ট ব্যতিক্রম ধরনের কি (জাভা হিসাবে) যত্ন করে না। জাভাস্ক্রিপ্ট শুধু নোটিশ, একটি ব্যতিক্রম আছে এবং আপনি এটি ধরা যখন, আপনি "বলছেন" ব্যতিক্রম কি "চেহারা" করতে পারেন।

যদি আপনার কাছে বিভিন্ন ধরণের ব্যতিক্রমগুলি থাকে তবে আপনাকে ভেরিয়েবলগুলি ব্যবহার করতে পরামর্শ দেওয়া হবে যা ব্যতিক্রমের স্ট্রিং / বস্তুটি ধারণ করে। যেখানে আপনি এটি ব্যবহার করতে চান "আমার ব্যতিক্রম ছুড়ে দিন" এবং ধরাতে, আমার ব্যতিক্রম থেকে ধরা ব্যতিক্রম তুলনা করুন।





exception-handling