ব্যতিক্রম বস্তুগুলি ছুঁড়ে ফেলার পরিবর্তে ফেরত দেওয়ার বৈধ কারণ রয়েছে?


45

এই প্রশ্নের ব্যতিক্রম হ্যান্ডলিং সমর্থন করে যে কোনও OO প্রোগ্রামিং ভাষা প্রয়োগ করতে; আমি কেবল চিত্রণমূলক উদ্দেশ্যে সি # ব্যবহার করছি।

ব্যতিক্রমগুলি সাধারণত উত্থাপিত হয় যখন কোনও সমস্যা দেখা দেয় যে কোডটি তাত্ক্ষণিকভাবে হ্যান্ডেল করতে পারে না এবং তারপরে catchকোনও পৃথক স্থানে (সাধারণত একটি বাইরের স্ট্যাক ফ্রেম) কোনও ধারায় ধরা পড়ে ।

প্রশ্ন: এমন কোনও বৈধ পরিস্থিতি রয়েছে যেখানে ব্যতিক্রম ছুঁড়ে ফেলা হয় না এবং ধরা পড়ে না, তবে কেবল কোনও পদ্ধতি থেকে ফিরে এসে ত্রুটিযুক্ত বস্তু হিসাবে পাস করা হয়?

এই প্রশ্নটি আমার জন্য উঠে এসেছিল কারণ। নেট 4 এর System.IObserver<T>.OnErrorপদ্ধতিটি কেবল এটাই প্রস্তাব করে: ব্যতিক্রম ত্রুটিযুক্ত বস্তু হিসাবে পাস হচ্ছে।

আসুন অন্য পরিস্থিতিতে দেখুন, বৈধতা। ধরা যাক আমি প্রচলিত জ্ঞান অনুসরণ করছি এবং তাই আমি একটি ত্রুটিযুক্ত অবজেক্টের ধরণ IValidationErrorএবং ValidationExceptionঅপ্রত্যাশিত ত্রুটিগুলি রিপোর্ট করার জন্য ব্যবহৃত একটি পৃথক ব্যতিক্রমের মধ্যে পার্থক্য করছি :

partial interface IValidationError { }

abstract partial class ValidationException : System.Exception
{
    public abstract IValidationError[] ValidationErrors { get; }
}

( System.Component.DataAnnotationsনামস্থানটি বেশ কিছু অনুরূপ কাজ করে))

এই ধরণের নিম্নলিখিত হিসাবে নিযুক্ত করা যেতে পারে:

partial interface IFoo { }  // an immutable type

partial interface IFooBuilder  // mutable counterpart to prepare instances of above type
{
    bool IsValid(out IValidationError[] validationErrors);  // true if no validation error occurs
    IFoo Build();  // throws ValidationException if !IsValid(…)
}

এখন আমি ভাবছি, আমি কি এইগুলির উপরেরটি সহজ করতে পারি না:

partial class ValidationError : System.Exception { }  // = IValidationError + ValidationException

partial interface IFoo { }  // (unchanged)

partial interface IFooBuilder
{
    bool IsValid(out ValidationError[] validationErrors);
    IFoo Build();  // may throw ValidationError or sth. like AggregateException<ValidationError>
}

প্রশ্ন: এই দুটি পৃথক পদ্ধতির সুবিধা এবং অসুবিধাগুলি কী?


আপনি যদি দুটি পৃথক উত্তর খুঁজছেন, আপনার দুটি পৃথক প্রশ্ন জিজ্ঞাসা করা উচিত। তাদের একত্রিত করা উত্তর দেওয়া এত কঠিন করে তোলে।
ববসন

2
@ সাবসন: আমি এই দুটি প্রশ্নকে পরিপূরক হিসাবে দেখছি: পূর্ববর্তী প্রশ্নটি ইস্যুটির সাধারণ প্রেক্ষাপটকে বিস্তৃতভাবে সংজ্ঞায়িত করার কথা বলে মনে করা হচ্ছে, তবে পরবর্তীতে সুনির্দিষ্ট তথ্য চেয়েছে যা পাঠকদের তাদের নিজস্ব উপসংহার টানতে দেয়। একটি উত্তর উভয় প্রশ্নের পৃথক, সুস্পষ্ট উত্তর দিতে হবে না; উত্তর "ইন-এর মধ্যে" ঠিক তেমন স্বাগত।
stakx

5
আমি কোনও কিছুর বিষয়ে অস্পষ্ট: ব্যতিক্রম থেকে বৈধতা এরর বের করার কারণ কী, যদি আপনি এটি ফেলে না চলে থাকেন?
pdr

@ পিডিআর: আপনার AggregateExceptionপরিবর্তে নিক্ষেপের ক্ষেত্রে কী বোঝাতে চাইছেন ? ভাল যুক্তি.
stakx

3
আসলে তা না. আমি বোঝাতে চাইছি যদি আপনি এটি নিক্ষেপ করতে যাচ্ছেন তবে একটি ব্যতিক্রম ব্যবহার করুন। আপনি যদি এটি ফিরিয়ে দিতে যাচ্ছেন তবে একটি ত্রুটিযুক্ত বস্তু ব্যবহার করুন। যদি আপনি প্রকৃতির দ্বারা প্রকৃতই ত্রুটিযুক্ত ব্যতিক্রমগুলি প্রত্যাশা করে থাকে তবে সেগুলি ধরুন এবং এটিকে আপনার ত্রুটিযুক্ত বস্তুতে রেখে দিন। একাধিক ত্রুটিগুলির জন্য কেউ অনুমতি দেয় কিনা তা সম্পূর্ণ অপ্রাসঙ্গিক।
pdr

উত্তর:


31

এমন কোনও বৈধ পরিস্থিতি রয়েছে যেখানে ব্যতিক্রম ছোঁড়া এবং ধরা পড়ে না, তবে কেবল কোনও পদ্ধতি থেকে ফিরে এসে ত্রুটিযুক্ত বস্তু হিসাবে প্রায় পেরিয়ে যায়?

যদি এটি কখনও নিক্ষেপ করা হয় না তবে এটি ব্যতিক্রম নয়। এটি derivedকোনও ব্যতিক্রম শ্রেণীর একটি বিষয় , যদিও এটি আচরণটি অনুসরণ করে না। একে ব্যতিক্রম বলা একেবারে শব্দার্থবিজ্ঞান এই মুহুর্তে, তবে আমি এটি নিক্ষেপ করাতে কোনও ভুল দেখছি না। আমার দৃষ্টিকোণ থেকে, কোনও ব্যতিক্রম ছোঁড়া না করা হ'ল অভ্যন্তরীণ ফাংশন হিসাবে এটি ধরা এবং প্রচার থেকে বাধা দেওয়া ঠিক একই জিনিস।

কোনও ফাংশন ব্যতিক্রম অবজেক্টগুলি ফিরিয়ে দেওয়া কি বৈধ?

একেবারে। উদাহরণগুলির একটি সংক্ষিপ্ত তালিকা এখানে এটি উপযুক্ত হতে পারে যেখানে:

  • একটি ব্যতিক্রম কারখানা।
  • একটি প্রসঙ্গ অবজেক্ট যা ব্যতিক্রম ব্যবহারের জন্য প্রস্তুত হিসাবে পূর্ববর্তী ত্রুটি ছিল কিনা তা রিপোর্ট করে।
  • একটি ফাংশন যা পূর্বে ধরা ব্যতিক্রম রাখে।
  • একটি তৃতীয় পক্ষের এপিআই যা কোনও অভ্যন্তরের প্রকারের ব্যতিক্রম তৈরি করে।

খারাপ লাগছে না?

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

এখানে গুরুত্বপূর্ণ বিষয়টি বুঝতে হবে যে ব্যতিক্রমগুলির আসল মানটি try/catchপ্যাটার্নে রয়েছে, ব্যতিক্রম অবজেক্টের ইনস্ট্যান্টেশন নয়। ব্যতিক্রম বস্তুটি কেবল একটি রাষ্ট্রীয় বার্তা।

আপনার প্রশ্নে আপনি এই দুটি জিনিসের ব্যবহারকে বিভ্রান্ত করছেন বলে মনে হচ্ছে: ব্যতিক্রমের কোনও হ্যান্ডলারের কাছে একটি জাম্পিং এবং ব্যতিক্রমটি ব্যতিক্রমটিকে প্রতিনিধিত্ব করে। আপনি একটি ত্রুটিযুক্ত স্থিতি নিয়েছেন এবং এটিকে ব্যতিক্রম হিসাবে মুড়িয়ে রাখার অর্থ এই নয় যে আপনি try/catchপ্যাটার্নটি বা এর সুবিধাগুলি অনুসরণ করছেন।


4
"যদি এটিকে কখনই ফেলে দেওয়া হয় না তবে এটি ব্যতিক্রম নয় It এটি একটি Exceptionশ্রেণি থেকে প্রাপ্ত একটি জিনিস তবে আচরণটি অনুসরণ করে না।" - এবং এটি হ'ল সমস্যাটি: Exceptionএমন কোনও পরিস্থিতিতে কোনও উত্সর্গীকৃত অবজেক্ট ব্যবহার করা কি বৈধ, যেখানে অবজেক্টটির নির্মাতারা বা কোনও কলিং পদ্ধতিতে তা নিক্ষেপযোগ্য হবে না; যেখানে এটি "সুপার রিটার্ন" নিয়ন্ত্রণ প্রবাহ ছাড়াই কেবল একটি "রাষ্ট্রীয় বার্তা" প্রদত্ত হিসাবে কাজ করে? বা আমি কি বলবত try/ catch(Exception)চুক্তিটি এত খারাপভাবে লঙ্ঘন করছি যে আমার কখনই এটি করা উচিত নয় এবং পরিবর্তে একটি পৃথক, অ- Exceptionটাইপ ব্যবহার করা উচিত ?
stakx

10
@ স্ট্যাকএক্স প্রোগ্রামারদের এমন কাজগুলি করা এবং চালিয়ে যেতে হবে যা অন্যান্য প্রোগ্রামারদের জন্য বিভ্রান্তিকর, তবে প্রযুক্তিগতভাবে ভুল নয়। সে কারণেই আমি বলেছিলাম এটি শব্দার্থবিজ্ঞান। আইনি উত্তরটি হ'ল Noআপনি কোনও চুক্তি ভঙ্গ করছেন না। আপনার popular opinionএমনটি করা উচিত নয়। প্রোগ্রামিং এমন উদাহরণগুলিতে পূর্ণ যেখানে আপনার উত্স কোডটি ভুল কিছু করে না তবে সবাই এটিকে অপছন্দ করে। উত্স কোড সর্বদা লেখা উচিত যাতে উদ্দেশ্যটি কী তা পরিষ্কার হয়ে যায়। আপনি কি এইভাবে ব্যতিক্রম ব্যবহার করে অন্য প্রোগ্রামারকে সত্যই সহায়তা করছেন? যদি হ্যাঁ, তবে তাই করুন। অন্যথায় এটি অপছন্দ হলে অবাক হবেন না।
আয়তাকার

@cgTag ইটালিক্সের জন্য আপনার ইনলাইন কোড ব্লক ব্যবহার আমার মস্তিস্ককে আঘাত করে তোলে ..
ফ্রেয়েট

51

যদি পরিস্থিতি বিশ্লেষণ করার জন্য কোনও সহায়ক-পদ্ধতি থাকে এবং তার পরে কলার দ্বারা নিক্ষিপ্ত একটি উপযুক্ত ব্যতিক্রম ফিরে আসে তখন তাদের ফেলে দেওয়ার পরিবর্তে ব্যতিক্রমগুলি প্রত্যাবর্তনের অর্থ শব্দার্থিক ধারণা তৈরি করতে পারে (আপনি এটিকে একটি "ব্যতিক্রম কারখানা" বলতে পারেন)। এই ত্রুটি বিশ্লেষক কার্যক্রমে একটি ব্যতিক্রম ছুঁড়ে ফেলার অর্থ এই হবে যে বিশ্লেষণের সময়ই কিছু ভুল হয়েছিল, যখন একটি ব্যতিক্রম প্রত্যাবর্তনের অর্থ দাঁড়ায় যে ধরণের ত্রুটিটি সফলভাবে বিশ্লেষণ করা হয়েছিল।

একটি সম্ভাব্য ব্যবহার-কেস একটি ফাংশন হতে পারে যা HTTP প্রতিক্রিয়া কোডগুলিকে ব্যতিক্রমগুলিতে রূপান্তরিত করে:

Exception analyzeHttpError(int errorCode) {
    if (errorCode < 400) {
         throw new NotAnErrorException();
    }
    switch (errorCode) {
        case 403:
             return new ForbiddenException();
        case 404:
             return new NotFoundException();
        case 500:
             return new InternalServerErrorException();
        …
        default:
             throw new UnknownHttpErrorCodeException(errorCode);
     }
}

নোট করুন যে একটি ব্যতিক্রম নিক্ষেপ করার অর্থ হল যে পদ্ধতিটি ভুলভাবে ব্যবহৃত হয়েছিল বা অভ্যন্তরীণ ত্রুটি ছিল, একটি ব্যতিক্রম ফিরিয়ে দেওয়ার অর্থ ত্রুটি কোডটি সফলভাবে চিহ্নিত করা হয়েছিল।


এটি কম্পাইলারকে কোড প্রবাহ বুঝতেও সহায়তা করে: যদি কোনও পদ্ধতি সঠিকভাবে কখনই ফিরে না আসে (কারণ এটি "পছন্দসই" ব্যতিক্রমটি ছুঁড়ে দেয়) এবং সংকলকটি সে সম্পর্কে জানে না, তবে সংক্ষেপকারকে returnঅভিযোগ করা বন্ধ করতে আপনার মাঝে মাঝে অতিরিক্ত অতিরিক্ত বিবৃতি প্রয়োজন হতে পারে ।
জোচিম সউর

@ জোছিমসৌর হ্যাঁ একাধিকবার আমি আশা করি তারা সি # তে "কখনই নয়" রিটার্নের ধরণ যুক্ত করবে - এটি নির্দেশ করে যে ফাংশনটি ছুঁড়ে দিয়ে বেরিয়ে আসতে হবে, এতে একটি রিটার্ন স্থাপন করা একটি ত্রুটি। কখনও কখনও আপনার কোড থাকে যার একমাত্র কাজ ব্যতিক্রম সুন্দর করে তুলছে।
লরেন পেচটেল

2
@ লরেনপেকটেল এমন একটি ফাংশন যা কখনই ফিরে আসে না কোনও ফাংশন নয়। এটি একটি টার্মিনেটর। এর মতো একটি ফাংশন কল করুন কলিং স্ট্যাক সাফ করে। এটি কল করার অনুরূপ System.Exit()। ফাংশন কলের পরে কোডটি কার্যকর করা হয় না। এটি কোনও ফাংশনের জন্য ভাল ডিজাইনের প্যাটার্নের মতো শোনাচ্ছে না।
চুল্লী

5
@ ম্যাথিউফোস্কারিণী এমন এক শ্রেণীর বিষয়ে বিবেচনা করুন যাতে একাধিক পদ্ধতি রয়েছে যা একই উপায়ে ত্রুটি করতে পারে। আপনি বর্ধিত হওয়ার সময় এটি কী চিবানো হয়েছিল তা বোঝাতে ব্যতিক্রমের অংশ হিসাবে কিছু রাষ্ট্রীয় তথ্য ফেলে দিতে চান। আপনি DRY এর কারণে চমত্কার কোডটির একটি অনুলিপি চান। এটি হয় এমন কোনও ফাংশনকে কল করে যা সুন্দর করে তোলে এবং ফলাফলটি আপনার ছোঁড়ার ফল ব্যবহার করে বা এর অর্থ এমন একটি ফাংশন যা প্রিটি-আপ টেক্সট তৈরি করে এবং তারপরে এটি ছুঁড়ে দেয়। আমি সাধারণত পরেরটি উচ্চতর দেখতে।
লরেন পেচটেল

1
@ লরেন পেচটেল আহ, হ্যাঁ আমি এটিও করেছি। ঠিক আছে আমি এখন বুঝতে পারি।
আয়তাকার

5

ধারণামূলকভাবে, যদি ব্যতিক্রম বস্তুটি অপারেশনের প্রত্যাশিত ফলাফল হয় তবে হ্যাঁ। আমি যে কেসগুলি সম্পর্কে ভাবতে পারি সেগুলি সর্বদা কোনও সময়ে থ্রো-ক্যাচ জড়িত:

  • "ট্রাই" প্যাটার্নের প্রকরণ (যেখানে কোনও পদ্ধতি দ্বিতীয় ব্যতিক্রম-নিক্ষেপ পদ্ধতিটিকে আবদ্ধ করে, তবে ব্যতিক্রমটিকে ধরে এবং পরিবর্তে একটি বুলিয়ান সাফল্যের ইঙ্গিত দেয়)। আপনি, কোনও বুলিয়ান ফিরিয়ে দেওয়ার পরিবর্তে, ছুঁড়ে ফেলে দেওয়া কোনও ব্যতিক্রম (যদি এটি সফল হয় তবে নাল) ফিরিয়ে দিতে পারবেন, ক্যাচ-কম সাফল্য বা ব্যর্থতার ইঙ্গিতটি ধরে রেখে শেষ ব্যবহারকারীকে আরও তথ্যের অনুমতি দিতে পারেন।

  • কর্মপ্রবাহ ত্রুটি প্রক্রিয়াজাতকরণ। "ট্র্যাফিক প্যাটার্ন" পদ্ধতি এনক্যাপসুলেশন অনুশীলনে অনুরূপ, আপনার একটি ওয়ার্কফ্লো পদক্ষেপটি চেইন-অফ-কমান্ড প্যাটার্নটিতে বিমূর্ত হতে পারে। যদি শৃঙ্খলে থাকা কোনও লিঙ্কটি ব্যতিক্রম ছুঁড়ে ফেলে তবে প্রায়শই পরিষ্কার হয় যে ব্যতিক্রমী অবজেক্টে এই ব্যতিক্রমটি ধরা যায়, তারপরে বলেছিলেন ক্রিয়াকলাপের ফলে এটি ফিরিয়ে দিন যাতে ওয়ার্কফ্লো ইঞ্জিন এবং প্রকৃত কোডটি একটি ওয়ার্কফ্লো পদক্ষেপ হিসাবে চালিত করার জন্য বিস্তৃত চেষ্টা করার প্রয়োজন নেই তাদের নিজস্ব যুক্তি ধরুন।


আমি মনে করি না যে কোনও উল্লেখযোগ্য লোক "ট্রাই" প্যাটার্নে এই জাতীয় পরিবর্তনের পক্ষে ছিলেন, তবে বুলিয়ানকে ফিরিয়ে দেওয়ার "প্রস্তাবিত" পদ্ধতিটি বেশ রক্তাল্প বলে মনে হয়। আমি মনে করব OperationResultএকটি boolসম্পত্তি "সাফল্যবান", একটি GetExceptionIfAnyপদ্ধতি এবং একটি AssertSuccessfulপদ্ধতি (যা GetExceptionIfAnyনন-নাল থেকে বাদ দিলে) সহ একটি বিমূর্ত শ্রেণি রাখা ভাল । রয়ে GetExceptionIfAnyএকটি পদ্ধতি বদলে একটি সম্পত্তি ক্ষেত্রে যেখানে অনেক বলার দরকারী ছিল না জন্য স্ট্যাটিক অপরিবর্তনীয় ত্রুটি বস্তুর ব্যবহার সম্ভব হবে হবে।
সুপারক্যাট

5

বলুন যে আপনি কিছু থ্রেড পুলে সম্পাদন করতে কোনও টাস্ক অর্জন করেছেন। যদি এই কাজটি ব্যতিক্রম ছুঁড়ে, এটি আলাদা থ্রেড তাই আপনি এটি ধরেন না। থ্রেড যেখানে এটি কার্যকর করা হয়েছিল কেবল মারা যান।

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

আপনি যদি এটি ম্যানুয়ালি করেন তবে আপনি খেয়াল করতে পারেন যে আপনি নতুন ব্যতিক্রম তৈরি করছেন, এটি ছুঁড়ে ফেলেছেন এবং ধরছেন, তারপরে এটি সংরক্ষণ করে, বিভিন্ন থ্রেডে ছোঁড়া পুনরুদ্ধার করা, ধরা এবং তাতে প্রতিক্রিয়া দেখানো। সুতরাং এটি ফেলে দেওয়া এবং ধরা এবং কেবল এটি সঞ্চয় করে টাস্ক শেষ করা এবং তারপরে ব্যতিক্রম আছে কিনা এবং এটিতে প্রতিক্রিয়া জানাতে কেবল তা জিজ্ঞাসা করতে পারে। যদি একই জায়গায় সত্যিকারের ব্যতিক্রম ছুঁড়ে ফেলা যায় তবে এটি আরও জটিল কোডের দিকে নিয়ে যেতে পারে।

পিএস: এটি জাভা সহ অভিজ্ঞতার সাথে লেখা হয়েছে, যেখানে ব্যতিক্রম তৈরি হওয়ার সময় স্ট্যাক ট্রেস তথ্য তৈরি করা হয় (সি # এর বিপরীতে যেখানে এটি নিক্ষেপ করার সময় তৈরি করা হয়)। সুতরাং জাভাতে নিক্ষিপ্ত ব্যতিক্রম পদ্ধতি সি # এর তুলনায় ধীর হবে (যদি না পূর্ববর্তী এবং পুনরায় ব্যবহৃত হয়) তবে এতে স্ট্যাক ট্রেস তথ্য উপলব্ধ থাকবে।

সাধারণভাবে, আমি ব্যতিক্রম তৈরি করা এবং এটিকে কখনও ছুঁড়ে ফেলার থেকে দূরে থাকব (প্রোফাইলিংয়ের পরে পারফরম্যান্স অনুকূলকরণ হিসাবে এটি বাধা হিসাবে চিহ্নিত না করে)। অন্তত জাভাতে, যেখানে ব্যতিক্রমী ব্যয় ব্যয়বহুল (স্ট্যাক ট্রেস)। সি # তে এটি সম্ভাবনা, তবে আইএমও এটি অবাক করে তোলে এবং তাই এড়ানো উচিত।


এটি প্রায়শই ত্রুটি শ্রোতাদের সাথে ঘটে। একটি সারি কার্য সম্পাদন করবে, যে কোনও ব্যতিক্রম ধরবে, তারপরে ত্রুটি শ্রোতাকে দায়ী হিসাবে সেই ব্যতিক্রমটি পাস করবে। সাধারণত টাস্ক থ্রেডটি মেরে ফেলা উচিত নয় যা এই ক্ষেত্রে কাজ সম্পর্কে খুব বেশি জানে না। এই ধরণের ধারণাটি জাভা এপিআইগুলিতেও অন্তর্নির্মিত হয়েছে যেখানে একটি থ্রেড অন্যের কাছ থেকে ব্যতিক্রমগুলি পেতে পারে: ডকস.অরাকল.com
ল্যান্স নানেক

1

এটি আপনার নকশার উপর নির্ভর করে, সাধারণত আমি একজন আহ্বানকারীকে ব্যতিক্রম ফিরিয়ে দেব না, বরং আমি তাদের ছুঁড়ে ফেলতাম এবং ধরে ফেলতাম এবং এটিকেই ছেড়ে দেব। সাধারণত কোডটি তাড়াতাড়ি এবং দ্রুত ব্যর্থ হওয়ার জন্য লেখা হয়। উদাহরণস্বরূপ কোনও ফাইল খোলার এবং এটি প্রক্রিয়া করার ক্ষেত্রে বিবেচনা করুন (এটি সি # PsuedoCode):

        private static void ProcessFileFailFast()
        {
            try
            {
                using (var file = new System.IO.StreamReader("c:\\test.txt"))
                {
                    string line;
                    while ((line = file.ReadLine()) != null)
                    {
                        ProcessLine(line);
                    }
                }
            }
            catch (Exception ex) 
            {
                LogException(ex);
            }
        }

        private static void ProcessLine(string line)
        {
            //TODO:  Process Line
        }

        private static void LogException(Exception ex)
        {
            //TODO:  Log Exception
        }

এই ক্ষেত্রে, আমরা কোনও ত্রুটি রেকর্ডের সম্মুখীন হওয়ার সাথে সাথে ফাইলটি ত্রুটিযুক্ত করে প্রক্রিয়াজাতকরণ বন্ধ করব।

তবে বলুন প্রয়োজনীয়তাটি হ'ল আমরা এক বা একাধিক লাইনে ত্রুটি থাকলেও আমরা ফাইলটি প্রক্রিয়া চালিয়ে যেতে চাই। কোডটি এরকম কিছু দেখতে শুরু করতে পারে:

    private static void ProcessFileFailAndContinue()
    {
        try
        {
            using (var file = new System.IO.StreamReader("c:\\test.txt"))
            {
                string line;
                while ((line = file.ReadLine()) != null)
                {
                    Exception ex = ProcessLineReturnException(line);
                    if (ex != null)
                    {
                        _Errors.Add(ex);
                    }
                }
            }

            //Do something with _Errors Here
        }
        //Catch errors specifically around opening the file
        catch (System.IO.FileNotFoundException fnfe) 
        { 
            LogException(fnfe);
        }    
    }

    private static Exception ProcessLineReturnException(string line)
    {
        try
        {
            //TODO:  Process Line
        }
        catch (Exception ex)
        {
            LogException(ex);
            return ex;
        }

        return null;
    }

সুতরাং এই ক্ষেত্রে আমরা কলারের কাছে ব্যতিক্রমটি ফিরিয়ে দিই, যদিও আমি সম্ভবত ব্যতিক্রমটি ফিরিয়ে আনব না তবে ব্যতিক্রমটি ধরা পড়ে এবং ইতিমধ্যে মোকাবেলা করার কারণে কিছুটা ত্রুটিযুক্ত বস্তু ফিরে আসবে। ব্যতিক্রম ফিরিয়ে দেওয়ার সাথে এটি কোনও ক্ষতি নয় তবে অন্যান্য কলকারীরা ব্যতিক্রমটিকে পুনরায় নিক্ষেপ করতে পারে যা ব্যতিক্রমী অবজেক্টের আচরণের কারণে আকাঙ্ক্ষিত হতে পারে না। যদি আপনি চেয়েছিলেন কলকারীদের পুনরায় নিক্ষেপ করার ক্ষমতা রয়েছে তবে একটি ব্যতিক্রম ফিরিয়ে দিন, অন্যথায়, ব্যতিক্রম বস্তুর বাইরে তথ্যটি নিয়ে যান এবং একটি ছোট হালকা ওজনের অবজেক্ট তৈরি করুন এবং পরিবর্তে সেটি ফিরিয়ে দিন। ব্যর্থ দ্রুত সাধারণত ক্লিনার কোড হয়।

আপনার বৈধতা উদাহরণের জন্য, আমি সম্ভবত একটি ব্যতিক্রম শ্রেণীর উত্তরাধিকারী হইব না বা ব্যতিক্রম নিক্ষেপ করব না কারণ বৈধতা ত্রুটিগুলি বেশ সাধারণ হতে পারে। আমার ব্যবহারকারীর ৫০% যদি প্রথম প্রচেষ্টাটিতে সঠিকভাবে কোনও ফর্ম পূরণ করতে ব্যর্থ হয় তবে কোনও আপত্তি ছুঁড়ে ফেলার চেয়ে কোনও জিনিস ফেরত দেওয়া কম ওভারহেড হবে be


1

প্রশ্ন: এমন কোনও বৈধ পরিস্থিতি রয়েছে যেখানে ব্যতিক্রম ছুঁড়ে ফেলা হয় না এবং ধরা পড়ে না, তবে কেবল কোনও পদ্ধতি থেকে ফিরে এসে ত্রুটিযুক্ত বস্তু হিসাবে পাস করা হয়?

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

দৃষ্টান্তমূলক কোড:

Public Sub SomeWebMethod()
    Try
        ...
    Catch ex As Exception
        Dim soapex As SoapException = Me.GenerateSoapFault(ex)
        Throw soapex
    End Try
End Sub

Private Function GenerateSoapFault(ex As Exception) As SoapException
    Dim document As XmlDocument = New XmlDocument()
    Dim faultDetails As XmlNode = document.CreateNode(XmlNodeType.Element, SoapException.DetailElementName.Name, SoapException.DetailElementName.Namespace)
    faultDetails.InnerText = ex.Message
    Dim exceptionType As String = ex.GetType().ToString()
    Dim soapex As SoapException = New SoapException("SoapException", SoapException.ClientFaultCode, Context.Request.Url.ToString, faultDetails)
    Return soapex
End Function

1

বেশিরভাগ ভাষায় (আফাইক) ব্যতিক্রম কিছু সংযুক্ত গুডিজ নিয়ে আসে। বেশিরভাগ ক্ষেত্রে, বর্তমান স্ট্যাক ট্রেসের একটি স্ন্যাপশট বস্তুটিতে সংরক্ষণ করা হয়। এটি ডিবাগিংয়ের জন্য দুর্দান্ত তবে এটির স্মৃতিশক্তিও থাকতে পারে।

@ থিংকিংমিডিয়া যেমন ইতিমধ্যে বলেছে, আপনি সত্যই ব্যতিক্রমটিকে ত্রুটিযুক্ত বস্তু হিসাবে ব্যবহার করছেন।

আপনার কোড উদাহরণে, মনে হয় আপনি মূলত কোড পুনরায় ব্যবহারের জন্য এবং রচনাটি এড়ানোর জন্য এটি করেন। আমি ব্যক্তিগতভাবে এটি এটি করার একটি ভাল কারণ বলে মনে করি না।

আর একটি সম্ভাব্য কারণ হ'ল ভাষাটিকে কৌতুক করা আপনাকে স্ট্যাক ট্রেসের সাহায্যে একটি ত্রুটিযুক্ত জিনিস দেওয়া। এটি আপনার ত্রুটি পরিচালনার কোডে অতিরিক্ত প্রাসঙ্গিক তথ্য দেয়।

অন্যদিকে, আমরা ধরে নিতে পারি যে স্ট্যাকের সন্ধানের চারপাশে রাখার জন্য একটি মেমরির ব্যয় হয়। যেমন আপনি যদি কোথাও এই জিনিসগুলি সংগ্রহ করতে শুরু করেন তবে আপনি একটি অপ্রীতিকর মেমরির প্রভাব দেখতে পাবেন। অবশ্যই এটি মূলত নির্ভর করে কীভাবে সম্পর্কিত ভাষা / ইঞ্জিনে ব্যতিক্রম স্ট্যাক ট্রেস প্রয়োগ করা হয়।

সুতরাং, এটি একটি ভাল ধারণা?

এখন পর্যন্ত আমি এটি ব্যবহার বা প্রস্তাবিত হতে দেখিনি। তবে এর বেশি অর্থ হয় না।

প্রশ্নটি হ'ল: স্ট্যাক ট্রেসটি কি আপনার ত্রুটি পরিচালনার জন্য সত্যই কার্যকর? বা আরও সাধারণভাবে, আপনি বিকাশকারী বা প্রশাসককে কোন তথ্য সরবরাহ করতে চান?

সাধারণ থ্রো / ট্রাই / ক্যাপচার প্যাটার্নটি স্ট্যাক ট্রেস থাকা এক ধরণের প্রয়োজনীয় করে তোলে কারণ অন্যথায় এটি কোথা থেকে আসছে তা আপনার কোনও ক্লু নেই। প্রত্যাবর্তিত বস্তুর জন্য, এটি সর্বদা ডাকা ফাংশন থেকে আসে। স্ট্যাক ট্রেসটিতে বিকাশকারীদের প্রয়োজনীয় সমস্ত তথ্য থাকতে পারে তবে কম ভারী এবং আরও নির্দিষ্ট কিছু হতে পারে।


-4

উত্তরটি হল হ্যাঁ. দেখুন http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Exceptions এবং ব্যতিক্রমগুলি গুগলের সি ++ শৈলী গাইড জন্য তীর খুলুন। তারা সেখানে যুক্তিগুলি যেগুলির বিরুদ্ধে সিদ্ধান্ত নিয়েছিল তা আপনি দেখতে পাচ্ছেন তবে বলবেন যে তাদের যদি আবার এটি করা হত তবে তারা সম্ভবত সিদ্ধান্ত নেবে।

তবে এটি লক্ষণীয় যে গো ভাষাটিও একই কারণে, ব্যতিক্রমগুলি আইডিয়োমেটিকালি ব্যবহার করে না।


1
দুঃখিত, তবে এই নির্দেশিকাগুলি কীভাবে প্রশ্নের উত্তর দিতে সহায়তা করে তা আমি বুঝতে পারি না: তারা কেবলমাত্র ব্যতিক্রম হ্যান্ডলিং পুরোপুরি এড়ানো উচিত বলে পরামর্শ দেয়। আমি এই বিষয়ে জিজ্ঞাসা করছি না; আমার প্রশ্ন হ'ল ফলশ্রুতিযুক্ত ব্যতিক্রম বস্তুটি কখনও ছুঁড়ে দেওয়া হবে না এমন পরিস্থিতিতে ত্রুটির শর্তটি বর্ণনা করার জন্য একটি ব্যতিক্রম প্রকারটি ব্যবহার করা বৈধ কিনা। এই নির্দেশিকাগুলিতে সে সম্পর্কে কিছুই নেই বলে মনে হয়।
stakx
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.