উত্তর:
শুধুমাত্র মানক ক্ষেত্রের ত্রুটিযুক্ত বস্তুটি 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
নিক্ষেপ করা হচ্ছে এমন বস্তুর বৈশিষ্ট্য। এই জিনিসগুলি সঠিক হওয়ার গ্যারান্টিযুক্ত।
আমি ব্যবহৃত পরীক্ষার কেসগুলি এখানে পাওয়া যাবে: জাভাস্ক্রিপ্ট স্ব-তৈরি ত্রুটিযুক্ত বস্তুর তুলনা ।
function MyError(message) { this.message = message; this.stack = Error().stack; } MyError.prototype = Object.create(Error.prototype); MyError.prototype.name = "MyError";
MyError.prototype.constructor = MyError
খুব।
this
, তাই না?
ES6 এ:
class MyError extends Error {
constructor(message) {
super(message);
this.name = 'MyError';
}
}
var supportsClasses = false; try {eval('class X{}'); supportsClasses = true;} catch (e) {}
this.name = this.constructor.name;
পরিবর্তে ব্যবহার করুন।
সংক্ষেপে:
আপনি যদি ট্রান্সপোর্টার ছাড়াই 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
class CustomError extends Error { /* ... */}
সঠিকভাবে বিক্রেতা-নির্দিষ্ট আর্গুমেন্টগুলি হ্যান্ডেল করে না ( lineNumber
ইত্যাদি), 'ইএস 6 সিনট্যাক্স সহ জাভাস্ক্রিপ্টে ত্রুটি প্রসারিত করা' বাবেল নির্দিষ্ট, আপনার ES5 সমাধান ব্যবহার করে const
এবং এটি কাস্টম আর্গুমেন্টগুলি পরিচালনা করে না।
console.log(new CustomError('test') instanceof CustomError);// false
লেখার সময় যে সমস্যাটি ছিল তা সত্য ছিল তবে এখন তা সমাধান হয়েছে বলে মনে করা যায় না। প্রকৃতপক্ষে উত্তরের সাথে যুক্ত সমস্যাটি সমাধান হয়ে গেছে এবং আমরা এখানে সঠিক আচরণটি পরীক্ষা করতে পারি এবং আরইপিএলে কোডটি আটকানো এবং সঠিক প্রোটোটাইপ শৃঙ্খলে এটি কীভাবে সঠিকভাবে স্থানান্তরিত হয় তা দেখে।
সম্পাদনা: মন্তব্য পড়ুন। এটি কেবল ভি 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
Error.call(this)
প্রকৃতপক্ষে কিছুই করছে যেহেতু এটি ফেরৎ পরিবর্তন চেয়ে একটি ত্রুটি বরং this
।
UserError.prototype = Error.prototype
বিভ্রান্তিকর। এটি উত্তরাধিকার করে না, এটি তাদেরকে একই বর্গ করে তোলে ।
Object.setPrototypeOf(this.constructor.prototype, Error.prototype)
পছন্দ করা this.constructor.prototype.__proto__ = Error.prototype
হয়।
করতে 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
ইতিমধ্যে প্রোটোটাইপে সেট করা আছে, এটি আর প্রয়োজন হয় না। আমি এটি সরিয়েছি। ধন্যবাদ!
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__
সম্পত্তি হ্রাস করা হয়েছে যা অন্যান্য উত্তরে ব্যাপকভাবে ব্যবহৃত হয়।
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 তে অন্তর্নির্মিত প্রসারিত / উত্তরাধিকার যুক্তি না থাকায় আপনাকে এটিকে পরিবর্তন করতে হবে। আমি নিশ্চিত আপনি বাবেল প্লাগইনটি একই জিনিসগুলি করে।
Object.setPrototypeOf
করে এখানে বোঝা যায় না, কমপক্ষে আপনি যেভাবে ব্যবহার করছেন তা নয়: gist.github.com/mbrowne/4af54767dcb3d529648f5a8aa11d6348 । সম্ভবত আপনি লিখতে চেয়েছিলেন Object.setPrototypeOf(CustomError.prototype, Error.prototype)
- এটি কিছুটা আরও অর্থবোধ তৈরি করবে (যদিও এখনও কেবল সেটিংয়ের উপর কোনও লাভ দেয় না CustomError.prototype
)।
সম্পূর্ণতার স্বার্থে - পূর্ববর্তী উত্তরগুলির মধ্যে কোনওটিই এই পদ্ধতির উল্লেখ করেনি - আপনি যদি নোড.জেএস এর সাথে কাজ করছেন এবং ব্রাউজারের সামঞ্জস্যতা সম্পর্কে যত্ন নিতে না চান তবে অন্তর্নির্মিত সাথে কাঙ্ক্ষিত প্রভাবটি অর্জন করা বেশ সহজ 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
তাত্ক্ষণিক হচ্ছে)। এটি কীভাবে কাজ করে সে সম্পর্কে আরও তথ্যের জন্য এখানে ডকুমেন্টেশন চেক করুন ।
this.message = this.message;
এটি কি ভুল বা এখনও কী পাগল জিনিস আমি জেএস সম্পর্কে জানি না?
ক্রিসেন্ট ফ্রেশের উত্তর সর্বাধিক ভোট দেওয়া উত্তর বিভ্রান্তিকর। যদিও তার সতর্কবাণীগুলি অবৈধ, অন্যান্য সীমাবদ্ধতাগুলিও সেটিকে সম্বোধন করে না।
প্রথমত, ক্রিসেন্টের "ক্যাভেটস:" অনুচ্ছেদে যুক্তিটি অর্থবোধ করে না। ব্যাখ্যাটি বোঝায় যে "একগুচ্ছ যদি (অন্যথায় ত্রুটির উদাহরণ) ..." একাধিক ক্যাচ স্টেটমেন্টের সাথে তুলনা করা একরকম বোঝা বা ভার্জোজ od একক ক্যাচ ব্লকে একাধিক উদাহরণ বিবৃতিগুলি একাধিক ক্যাচ স্টেটমেন্টের মতোই সংক্ষিপ্ত - কোনও কৌশল ছাড়াই পরিষ্কার এবং সংক্ষিপ্ত কোড। এটি জাভার দুর্দান্ত থ্রোয়েবল-সাব-টাইপ-নির্দিষ্ট ত্রুটি পরিচালনা পরিচালনা করার দুর্দান্ত উপায়।
ডাব্লুআরটি "সাবক্লাসের বার্তা বৈশিষ্ট্যটি সেট হয় না" প্রদর্শিত হয়, আপনি যদি সঠিকভাবে নির্মিত ত্রুটি সাবক্লাস ব্যবহার করেন তবে তা নয়। আপনার নিজের ত্রুটিএক্স ত্রুটি সাবক্লাসটি তৈরি করতে, "ভায় মাইরার =" দিয়ে কোড ব্লকের সূচনাটি অনুলিপি করুন, একটি শব্দ "মাইআরর" পরিবর্তন করে "ত্রুটিএক্স" করুন। (আপনি যদি আপনার সাবক্লাসে কাস্টম পদ্ধতি যুক্ত করতে চান তবে নমুনার পাঠ্যটি অনুসরণ করুন)।
জাভাস্ক্রিপ্ট ত্রুটি সাবক্লাসিংয়ের আসল এবং উল্লেখযোগ্য সীমাবদ্ধতাটি হ'ল যে জাভাস্ক্রিপ্ট বাস্তবায়ন বা ডিবাগারগুলি স্ট্যাক ট্রেস এবং অবস্থান-ইনস্ট্যান্টেশন সম্পর্কিত ফায়ারফক্সের মতো ট্র্যাক করে এবং প্রতিবেদন করে, তেমনি আপনার নিজের ত্রুটি সাবক্লাস বাস্তবায়নের কোনও অবস্থানটি ইনস্ট্যান্টেশন পয়েন্ট হিসাবে রেকর্ড করা হবে শ্রেণি, যদিও আপনি যদি সরাসরি ত্রুটি ব্যবহার করেন তবে এটি সেই জায়গা যেখানে আপনি "নতুন ত্রুটি (...)" চালিয়েছিলেন। আইই ব্যবহারকারীরা সম্ভবত লক্ষ্য করবেন না, তবে এফএফ-তে ফায়ার বাগের ব্যবহারকারীরা এই ত্রুটিগুলির পাশাপাশি প্রতিবেদন করা অযথা ফাইলের নাম এবং লাইন নম্বর মানগুলি দেখতে পাবেন এবং প্রকৃত তাত্ক্ষণিক অবস্থানের জন্য স্ট্যাক ট্রেসটিতে উপাদান # 1 এ ড্রিল করতে হবে।
Crescent Fresh's
মুছে ফেলা হয়েছে বলে কিছু বিভ্রান্তিকর !
কীভাবে এই সমাধান?
আপনার কাস্টম ত্রুটিটি ব্যবহার করার পরিবর্তে ব্যবহার করুন:
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();
};
new MyErr (arg1, arg2, new Error())
এবং মাইআরআর কন্সট্রাক্টরে আমরা Object.assign
শেষ this
কিছু লোক যেমন বলেছে, এটি 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;
}
}
আমার সমাধান সরবরাহ করা অন্যান্য উত্তরগুলির চেয়ে বেশি সহজ এবং ডাউনসাইড নেই।
এটি ত্রুটির প্রোটোটাইপ চেইন এবং ত্রুটির সমস্ত বৈশিষ্ট্যগুলির নির্দিষ্ট নির্দিষ্ট জ্ঞান ছাড়াই সংরক্ষণ করে। এটি ক্রোম, ফায়ারফক্স, নোড এবং আইই ১১ এ পরীক্ষা করা হয়েছে।
একমাত্র সীমাবদ্ধতা হ'ল কল স্ট্যাকের শীর্ষে একটি অতিরিক্ত প্রবেশ। তবে তা সহজেই উপেক্ষা করা হয়।
দুটি কাস্টম পরামিতি সহ এখানে একটি উদাহরণ:
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;
};
throw CustomError('err')
পরিবর্তে চালানো আবশ্যকthrow new CustomError('err')
উপরের উদাহরণে 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';
নোডে যেমন অন্যেরা বলেছেন, এটি সহজ:
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);
}
আমি অন্যরা যা ইতিমধ্যে বলেছে তাতে কেবল যুক্ত করতে চাই:
কাস্টম ত্রুটি শ্রেণীর স্ট্যাক ট্রেসটিতে সঠিকভাবে প্রদর্শিত হচ্ছে তা নিশ্চিত করার জন্য, আপনাকে কাস্টম ত্রুটি শ্রেণীর প্রোটোটাইপের নাম সম্পত্তিটি কাস্টম ত্রুটি শ্রেণির নাম বৈশিষ্ট্যে সেট করতে হবে। এটি আমার অর্থ:
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)
আমার 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__=
।
যেহেতু জাভাস্ক্রিপ্ট ব্যতিক্রমগুলি উপ-শ্রেণীর পক্ষে কঠিন, তাই আমি উপ-শ্রেণি করি না। আমি কেবলমাত্র একটি নতুন ব্যতিক্রম শ্রেণি তৈরি করেছি এবং এর ভিতরে একটি ত্রুটি ব্যবহার করব। আমি ত্রুটি.নাম সম্পত্তিটি পরিবর্তন করেছি যাতে এটি কনসোলে আমার কাস্টম ব্যতিক্রমের মতো দেখায়:
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);
m = new ...
তারপর Promise.reject(m)
। এটি কোনও প্রয়োজনীয়তা নয়, তবে কোডটি পড়া সহজ।
মোহসেনের উত্তরে যেমন উল্লেখ করা হয়েছে, 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 ব্যবহার করতে সক্ষম হব, ব্যক্তিগতভাবে আমি নিশ্চিত নই যে এই পদ্ধতির জটিলতা এটির পক্ষে উপযুক্ত।
এই অধিকারটি করার উপায়টি হ'ল কনস্ট্রাক্টরের কাছ থেকে প্রয়োগের ফলাফলটি ফিরে আসা, পাশাপাশি সাধারণ জটিল জাভাস্ক্রিপি পদ্ধতিতে প্রোটোটাইপ সেট করা:
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 এর দ্বিতীয় লাইনটি অপসারণ করা) () ??
স্নিপেট এটি সমস্ত দেখায়।
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)
}
}
আমি একটি পদক্ষেপ ফিরে নেব এবং আপনি কেন এটি করতে চান তা বিবেচনা করব? আমি মনে করি বিন্দুটি বিভিন্ন ত্রুটিগুলি ভিন্নভাবে মোকাবেলা করা।
উদাহরণস্বরূপ, পাইথনে, আপনি ক্যাচ স্টেটমেন্টটি কেবল ধরাতে সীমাবদ্ধ করতে পারেন 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
}
error.stack
, মানক সাধনী দ্বারা প্রয়োগকরণ হবে এটা দিয়ে কাজ না, ইত্যাদি ইত্যাদি একটি ভাল উপায় একটি ত্রুটি ক্ষেত্রটিকেই বৈশিষ্ট্যাবলী যোগ করার জন্য হবে, যেমনvar e = new Error(); e.type = "validation"; ...
এটি জর্জ বেইলের উত্তরের ভিত্তিতে , তবে মূল ধারণাটি প্রসারিত ও সরল করে তোলে। এটি কফিস্ক্রিপ্টে লিখিত, তবে জাভাস্ক্রিপ্টে রূপান্তর করা সহজ। ধারণাটি কোনও সাজসজ্জারের সাথে বেইলির কাস্টম ত্রুটিটি প্রসারিত করে যা এটি সহজেই মুছে ফেলে, আপনাকে সহজেই নতুন কাস্টম ত্রুটিগুলি তৈরি করতে দেয়।
দ্রষ্টব্য: এটি কেবল ভি 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চ্ছিক।
আপনি যদি ত্রুটিগুলির জন্য পারফরম্যান্সের বিষয়ে চিন্তা না করেন তবে এটি আপনার পক্ষে সবচেয়ে ছোট
Object.setPrototypeOf(MyError.prototype, Error.prototype)
function MyError(message) {
const error = new Error(message)
Object.setPrototypeOf(error, MyError.prototype);
return error
}
আপনি এটি কেবল নতুন MyError (বার্তা) ছাড়াই ব্যবহার করতে পারেন
কনস্ট্রাক্টর ত্রুটি বলা হওয়ার পরে প্রোটোটাইপ পরিবর্তন করে আমাদের কলস্ট্যাক এবং বার্তা সেট করতে হবে না
ইএস 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");
this.name = 'MyError'
ফাংশনটির বাইরের অংশটি সরিয়ে এটিকে পরিবর্তন করতে পারেনMyError.prototype.name = 'MyError'
।