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


224

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


3
সতর্ক থাকুন। 10 মিনিটে জাভাস্ক্রিপ্ট অনুসারে আপনি যদি একটি আনবক্সবিহীন মান নিক্ষেপ করেন তবে স্ট্যাক ট্রেস পাবেন না।
জানুস ট্রয়লসেন

ব্যাতিক্রম ডটকম কাস্টম ব্যতিক্রমগুলি তৈরি করার ক্ষমতা সরবরাহ করে এবং ডিফল্টরূপে আরগমেন্টএক্সেপশন এবং নটমিমপ্লিমেন্ট সহ কিছু অনুপস্থিত ব্যতিক্রম সরবরাহ করে।
স্টিভেন ওয়েক্সলার 4'14

উত্তর:


232

ওয়েব রেফারেন্স থেকে :

throw { 
  name:        "System Error", 
  level:       "Show Stopper", 
  message:     "Error detected. Please contact the system administrator.", 
  htmlMessage: "Error detected. Please contact the <a href=\"mailto:sysadmin@acme-widgets.com\">system administrator</a>.",
  toString:    function(){return this.name + ": " + this.message;} 
}; 

7
@ বি.লং এটি "জাভাস্ক্রিপ্ট: দ্য গুড পার্টস" (দুর্দান্ত বই আইএমও) -এ রয়েছে। এই Google বই প্রাকদর্শন শো অধ্যায়: books.google.com/books?id=PXa2bby0oQ0C&pg=PA32&lpg=PA32
orip

11
একটি স্ট্রিং পদ্ধতি যুক্ত করা এটি জাভাস্ক্রিপ্ট কনসোলটিতে দুর্দান্তভাবে প্রদর্শন করবে। এটি ছাড়াই এর মতো দেখায়: অচেনা # <অবজেক্ট> টস স্ট্রিংয়ের সাথে এটি প্রদর্শিত হচ্ছে: আনকচড সিস্টেম ত্রুটি: ত্রুটি সনাক্ত হয়েছে। সিস্টেম অ্যাডমিনস্ট্রেটরের সঙ্গে যোগাযোগ করুন।
জেডিসি

11
আপনি ত্রুটি থেকে উত্তরাধিকারী না হলে এটি আপনাকে ট্রেসগুলি সজ্জিত করতে অনুমতি দেবে না
লুক এইচ

কেবলমাত্র এই কাস্টম ত্রুটি নিয়ে কাজ করতে আপনি কীভাবে কোনও ক্যাচ ব্লকের মধ্যে ফিল্টার করতে পারেন?
ওভারড্রাইভার

@overdrivr কিছু ⦃মত catch (e) { if (e instanceof TypeError) { … } else { throw e; } }⦄ বা ⦃ catch (e) { switch (e.constructor) { case TypeError: …; break; default: throw e; }⦄।
সাম বুসালিস

92

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

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 বর্ধিতকরণ যে স্ট্যাকের ট্রেস Firefox এবং অন্যান্য ব্রাউজার কাজ সাথে উপরে পোস্ট করা হয়েছে। এটি তার পোস্ট করা একই পরীক্ষাগুলি সন্তুষ্ট করে:

ব্যবহার:

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!

80

আপনি এখানে নিজের মতো করে নিজের ব্যতিক্রম এবং তাদের পরিচালনা পরিচালনা করতে পারেন:

// 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");
    }
}

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

// 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");
}

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

40

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


26
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();
}

আপনি যদি ত্রুটির প্রোটোটাইপ উত্তরাধিকারসূত্রে না পেয়েও এই সংক্ষিপ্ত উদাহরণটি ঠিক একইভাবে কাজ করবে না? এটি এই উদাহরণে আপনাকে কী লাভ করে তা আমার কাছে স্পষ্ট নয়।
এলেগারটিও

1
না, e instanceof Errorমিথ্যা হবে।
মরগান এআরআর অ্যালেন

প্রকৃতপক্ষে. তবে যেহেতু e instanceof MyErrorসত্য হবে, else if(e instanceof Error)বিবৃতি কখনও মূল্যায়ন করা হবে না।
এলেগারটিও

ঠিক আছে, এটি চেষ্টা / ধরার এই স্টাইলটি কীভাবে কাজ করবে তার একটি উদাহরণ। কোথায় else if(e instanceof Error)হবে শেষ ক্যাচ। সম্ভবত একটি সাধারণ else(যা আমি অন্তর্ভুক্ত করি না) অনুসরণ করে। default:স্যুইচ স্টেটমেন্টের মতো বাছাই করুন ত্রুটির জন্য।
মরগান এআরআর অ্যালেন

15

সংক্ষেপে:

বিকল্প 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) {
      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;
    }
  • বিকল্প: ক্লাস্ট্রোফোবিক কাঠামো ব্যবহার করুন

ব্যাখ্যা:

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

11

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

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;
    }

})();

রিসাল্ট হিসাবে আমরা পাই

/**
 * 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:

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কনস্ট্রাক্টর কল অন্তর্ভুক্ত হবে না (ভি 8 এর জন্য ধন্যবাদ Error.captureStackTrace())।

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


2
Error.apply(self, arguments)কাজ না করার জন্য নির্দিষ্ট করা হয়েছে । আমি পরিবর্তে স্ট্যাক ট্রেস অনুলিপি করার পরামর্শ দিচ্ছি যা ক্রস ব্রাউজারের সাথে সামঞ্জস্যপূর্ণ।
কর্নেল

11

আমি প্রায়শই প্রোটোটাইপাল উত্তরাধিকার সহ একটি পন্থা ব্যবহার করি। ওভাররাইডিং 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();

8

ES6

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

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

7

নিক্ষেপ ব্যবহার করুন বিবৃতি ।

ব্যতিক্রম প্রকারটি (জাভা যেমন করে) জাভাস্ক্রিপ্ট কোনও যত্ন করে না। জাভাস্ক্রিপ্ট ঠিক লক্ষ্য করেছে, একটি ব্যতিক্রম আছে এবং যখন আপনি এটি ধরেন, আপনি ব্যতিক্রমটি কী বলে "দেখতে" পারেন।

যদি আপনার আলাদা ব্যতিক্রম প্রকারের আপনাকে ফেলে দিতে হয় তবে আমি এমন পরিবর্তনগুলি ব্যবহার করতে পরামর্শ দেব যার মধ্যে ব্যতিক্রমের স্ট্রিং / অবজেক্ট অর্থাৎ বার্তা রয়েছে। যেখানে আপনার এটি "থ্রো মাই এক্সেপশন" ব্যবহার করতে হবে এবং ক্যাচগুলিতে, ধরা ব্যতিক্রমটিকে আমার এক্সেপশনটির সাথে তুলনা করুন।


1

এমডিএন-তে এই উদাহরণটি দেখুন ।

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

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;

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



1
//create error object
var error = new Object();
error.reason="some reason!";

//business function
function exception(){
    try{
        throw error;
    }catch(err){
        err.reason;
    }
}

এখন আমরা ত্রুটিযুক্ত বস্তুতে যুক্তি বা যাবতীয় বৈশিষ্ট্য যুক্ত করতে এবং এটি পুনরুদ্ধার করে সেট করেছি। ত্রুটি আরও যুক্তিসঙ্গত করে।

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