বিবেচনাগুলি পরিচালনা করার সময় ত্রুটি


31

সমস্যাটি:

দীর্ঘদিন থেকে, আমি এই exceptionsপ্রক্রিয়াটি সম্পর্কে উদ্বিগ্ন , কারণ আমি অনুভব করি যে এটির কী হওয়া উচিত তা সত্যিই সমাধান করে না।

দাবি: এই বিষয় সম্পর্কে বাইরে দীর্ঘ বিতর্ক রয়েছে এবং তাদের বেশিরভাগ exceptionsএকটি ত্রুটি কোড ফেরত বনাম তুলনা করতে লড়াই করে । এটি এখানে অবশ্যই বিষয় নয়।

একটি ত্রুটি সংজ্ঞায়িত করার চেষ্টা করে, আমি সিজনপোরের গাইডলাইনগুলির সাথে সম্মত হব, বজর্ন স্ট্রস্ট্রপ এবং হার্ব সটার থেকে

একটি ত্রুটির অর্থ হল যে ফাংশনটি তার বিজ্ঞাপনিত উদ্দেশ্য অর্জন করতে পারে না

দাবি: exceptionপ্রক্রিয়াটি হ'ল ত্রুটিগুলি পরিচালনা করার জন্য একটি ভাষা অর্থসূচক।

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

দাবি: প্রাক বা পোস্ট শর্তটি যখন রক্ষণ না করা হয় তা নির্দেশ করার জন্য ব্যতিক্রমগুলি ব্যবহার করা exceptionমূলত ডিবাগিংয়ের উদ্দেশ্যে, প্রক্রিয়াটির অন্য একটি উদ্দেশ্য। আমি exceptionsএখানে এই ব্যবহার লক্ষ্যবস্তু না ।

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

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

এর দুটি পরিণতি রয়েছে:

  1. ঘন ঘন ঘটে যাওয়া ত্রুটিগুলি বিকাশের প্রথম দিকে সনাক্ত হয় এবং ডিবাগ হয় (যা ভাল)।
  2. বিরল ব্যতিক্রমগুলি পরিচালনা করা হয় না এবং ব্যবহারকারীর বাড়িতে সিস্টেমটি ক্র্যাশে পরিণত হয় (একটি দুর্দান্ত লগ বার্তা সহ)। কিছু সময় ত্রুটি রিপোর্ট করা হয়, এমনকি না।

এটি বিবেচনা করে, আইএমও ত্রুটি ব্যবস্থার মূল উদ্দেশ্যটি হওয়া উচিত:

  1. কোডে দৃশ্যমান করুন যেখানে কিছু নির্দিষ্ট কেস পরিচালিত হয় না।
  2. এই পরিস্থিতিটি ঘটলে সম্পর্কিত রানটাইমটি সম্পর্কিত কোডে যোগাযোগ করুন (কমপক্ষে কলার)।
  3. পুনরুদ্ধার প্রক্রিয়া সরবরাহ করে

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

ভাষাটি তত্ক্ষণাত কোডের প্রয়োগ যেমন তত্ক্ষণাত্ ভাষাটির অন্যান্য দিকগুলির (যেমন শক্তিশালী প্রকারের ভেরিয়েবল) হিসাবে করা হয় না

সমাধানের জন্য চেষ্টা

এটির উন্নতি করার অভিপ্রায়ে আমি একটি খুব সাধারণ ত্রুটি পরিচালনার ব্যবস্থা তৈরি করেছি, যা ত্রুটিটি পরিচালনা করার বিষয়টি স্বাভাবিক কোডের চেয়ে একই স্তরে গুরুত্বের চেষ্টা করে।

ধারণাটি হ'ল:

  • প্রতিটি (প্রাসঙ্গিক) ফাংশন একটি successখুব হালকা অবজেক্টের জন্য একটি রেফারেন্স গ্রহণ করে এবং এটি ক্ষেত্রে ত্রুটির স্থিতিতে সেট করতে পারে। পাঠ্য সহ একটি ত্রুটি সংরক্ষণ না হওয়া অবধি অবজেক্টটি খুব হালকা।
  • প্রদত্ত বস্তুটিতে ইতিমধ্যে কোনও ত্রুটি থাকলে কোনও ফাংশনটি তার কাজটি এড়াতে উত্সাহিত করা হয়।
  • কোনও ত্রুটি কখনই ওভাররাইড করা উচিত নয়।

সম্পূর্ণ নকশা স্পষ্টতই প্রতিটি দিককে (প্রায় 10 পৃষ্ঠা) পুরোপুরি বিবেচনা করবে, কীভাবে এটি ওওপিতে প্রয়োগ করা যায়।

Successশ্রেণীর উদাহরণ :

class Success
{
public:
    enum SuccessStatus
    {
        ok = 0,             // All is fine
        error = 1,          // Any error has been reached
        uninitialized = 2,  // Initialization is required
        finished = 3,       // This object already performed its task and is not useful anymore
        unimplemented = 4,  // This feature is not implemented already
    };

    Success(){}
    Success( const Success& v);
    virtual ~Success() = default;
    virtual Success& operator= (const Success& v);

    // Comparators
    virtual bool operator==( const Success& s)const { return (this->status==s.status && this->stateStr==s.stateStr);}
    virtual bool operator!=( const Success& s)const { return (this->status!=s.status || this->stateStr==s.stateStr);}

    // Retrieve if the status is not "ok"
    virtual bool operator!() const { return status!=ok;}

    // Retrieve if the status is "ok"
    operator bool() const { return status==ok;}

    // Set a new status
    virtual Success& set( SuccessStatus status, std::string msg="");
    virtual void reset();

    virtual std::string toString() const{ return stateStr;}
    virtual SuccessStatus getStatus() const { return status; }
    virtual operator SuccessStatus() const { return status; }

private:
    std::string stateStr;
    SuccessStatus status = Success::ok;
};

ব্যবহার:

double mySqrt( Success& s, double v)
{
    double result = 0.0;
    if (!s) ; // do nothing
    else if (v<0.0) s.set(Error, "Square root require non-negative input.");
    else result = std::sqrt(v);
    return result;
}

Success s;
mySqrt(s, 144.0);
otherStuff(s);
saveStuff(s);
if (s) /*All is good*/;
else cout << s << endl;

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

প্রশ্নটি

আমি একটি প্রকল্পে যেমন একটি দৃষ্টান্ত ব্যবহারের প্রভাব আরও ভাল বুঝতে চাই:

  • সমস্যার ভিত্তিটি কি সঠিক? বা আমি কি প্রাসঙ্গিক কিছু মিস করেছি?
  • সমাধানটি কি একটি ভাল স্থাপত্যের ধারণা? নাকি দাম খুব বেশি?

সম্পাদনা করুন:

পদ্ধতির মধ্যে তুলনা:

//Exceptions:

    // Incorrect
    File f = open("text.txt"); // Could throw but nothing tell it! Will crash
    save(f);

    // Correct
    File f;
    try
    {
        f = open("text.txt");
        save(f);
    }
    catch( ... )
    {
        // do something 
    }

//Error code (mixed):

    // Incorrect
    File f = open("text.txt"); //Nothing tell you it may fail! Will crash
    save(f);

    // Correct
    File f = open("text.txt");
    if (f) save(f);

//Error code (pure);

    // Incorrect
    File f;
    open(f, "text.txt"); //Easy to forget the return value! will crash
    save(f);

    //Correct
    File f;
    Error er = open(f, "text.txt");
    if (!er) save(f);

//Success mechanism:

    Success s;
    File f;
    open(s, "text.txt");
    save(s, f); //s cannot be avoided, will never crash.
    if (s) ... //optional. If you created s, you probably don't forget it.

25
"এই প্রশ্নটি গবেষণার প্রচেষ্টা দেখায়; এটি কার্যকর এবং স্পষ্ট" এর জন্য উত্সাহপ্রাপ্ত, আমি একমত হওয়ার কারণে নয়: আমি মনে করি বেশ কয়েকটি ধারণা বিপথগামী। (বিশদ একটি উত্তরে অনুসরণ করতে পারে))
মার্টিন বা

2
অবশ্যই, আমি বুঝতে এবং এটিতে সম্মত! সমালোচনা করা এই প্রশ্নের উদ্দেশ্য। এবং প্রশ্নের স্কোর ভাল / খারাপ প্রশ্নগুলি ইঙ্গিত করার জন্য, ওপি সঠিক নয়।
অ্যাড্রিয়ান মাইয়ার

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

3
শুধু সোনার মতো কিছু ব্যবহার করবেন না কেন? তারা আপনার ত্রুটিগুলি অন্তর্ভুক্ত করে তবে রান চলাকালীন তারা চুপ করে না। আসলে, আপনার কোডটি দেখার সময় আমি প্রথম যে জিনিসটি ভেবেছিলাম তা হ'ল "মনডস, দুর্দান্ত"। তাদের এক নজরে দেখুন।
bash0r

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

উত্তর:


32

ত্রুটি-পরিচালনা করা সম্ভবত কোনও প্রোগ্রামের সবচেয়ে শক্ত অংশ।

সাধারণভাবে, বুঝতে পারে যে ত্রুটির শর্ত রয়েছে সহজ; তবে এটিকে এমনভাবে সংকেত দেওয়া যাতে পরিবেষ্টন করা যায় না এবং এটি যথাযথভাবে পরিচালনা করা হয় ( আব্রাহামের ব্যতিক্রমী সুরক্ষা স্তর দেখুন ) সত্যিই শক্ত hard

সি তে, সিগন্যালিং ত্রুটিগুলি একটি রিটার্ন কোড দ্বারা সম্পন্ন হয়, যা আপনার সমাধানের জন্য বিস্ময়কর।

সি ++ এরূপ পদ্ধতির স্বল্প-আগমনের কারণে ব্যতিক্রমগুলি প্রবর্তিত ; যথা, এটি কেবল তখনই কাজ করে যদি কলাররা কোনও ত্রুটি ঘটেছে কিনা তা যাচাই করতে মনে রাখে এবং অন্যথায় ভয়াবহভাবে ব্যর্থ হয়। যখনই আপনি নিজেকে "প্রতিবার যতক্ষণ ঠিক আছে ..." বলে মনে করেন আপনার সমস্যা আছে; মানুষ তার যত্ন নেওয়ার পরেও তেমন সাবধানী নয়।

তবে সমস্যাটি হ'ল ব্যতিক্রমগুলির নিজস্ব সমস্যা রয়েছে। যথা, অদৃশ্য / লুকানো নিয়ন্ত্রণ প্রবাহ। এটি উদ্দেশ্যযুক্ত ছিল: ত্রুটি কেসটি গোপন করা যাতে কোডটির যুক্তি ত্রুটি পরিচালনা করে বোয়লারপ্লেটে আবদ্ধ না হয়। এটি "সুখী পথ "টিকে আরও স্পষ্ট করে তোলে (এবং দ্রুত!) ত্রুটির রাস্তাগুলি অনিচ্ছাকৃত করার জন্য ব্যয় করে।


অন্যান্য ভাষাগুলি কীভাবে ইস্যুটির দিকে নজর দেয় তা আমি আকর্ষণীয় মনে করি:

  • জাভা ব্যতিক্রমগুলি পরীক্ষা করেছে (এবং চেক করা নেই),
  • গো ত্রুটি কোড / প্যানিক ব্যবহার করে,
  • মরিচা যোগফলগুলি / প্যানিকগুলি ব্যবহার করে )।
  • সাধারণভাবে এফপি ভাষা।

সি ++ কিছু চেক করা ব্যাতিক্রমের ফর্ম ব্যবহার করত, আপনি লক্ষ্য করেছেন যে এটির noexcept(<bool>)পরিবর্তে এটি একটি মৌলিক দিকে অবচয় এবং সরল করা হয়েছে : হয় কোনও ফাংশন সম্ভবত ছুঁড়ে ফেলার ঘোষণা করা হয়, বা এটি কখনই না ঘোষণা করা হয়। চেক করা ব্যতিক্রমগুলি কিছুটা সমস্যাযুক্ত কারণ এগুলির এক্সটেনসিটির অভাব রয়েছে, যা বিশ্রী ম্যাপিং / বাসা বাঁধার কারণ হতে পারে। এবং সংশ্লেষিত ব্যতিক্রম শ্রেণিবিন্যাস (ভার্চুয়াল উত্তরাধিকারের প্রথম ব্যবহারের ক্ষেত্রে একটি ব্যতিক্রম ...)।

বিপরীতে, গো এবং মরিচা এমন পদ্ধতি গ্রহণ করে যা:

  • ত্রুটিগুলি ব্যান্ডে সিগন্যাল করা উচিত,
  • ব্যতিক্রম সত্যিই ব্যতিক্রমী পরিস্থিতিতে ব্যবহার করা উচিত।

পরেরটি বরং এটি স্পষ্টতই স্পষ্ট হয় যে (1) তারা তাদের ব্যতিক্রমগুলির আতঙ্কের নাম দেয় এবং (2) এখানে কোনও ধরণের শ্রেণিবিন্যাস / জটিল ধারা নেই। ভাষা "আতঙ্কের" বিষয়বস্তু পরিদর্শন করার জন্য সুবিধাগুলি সরবরাহ করে না: কোনও ধরণের শ্রেণিবিন্যাস, কোনও ব্যবহারকারী-সংজ্ঞায়িত সামগ্রী নয়, কেবল একটি "উফ, বিষয়গুলি এতটা ভুল হয়ে গেছে যে কোনও সম্ভাব্য পুনরুদ্ধার নেই"।

এটি কার্যকরভাবে ত্রুটি পরিচালনার জন্য ব্যবহারকারীদের কার্যকরভাবে উত্সাহিত করে, যদিও এখনও ব্যতিক্রমী পরিস্থিতিতে জামিনের সহজ উপায় ছেড়ে যায় (যেমন: "অপেক্ষা করুন, আমি এখনও এটি বাস্তবায়ন করি নি!")।

অবশ্যই, দুর্ভাগ্যক্রমে গো পন্থাটি আপনার মত অনেকের মতো যাতে আপনি সহজেই ত্রুটিটি পরীক্ষা করতে ভুলে যেতে পারেন ...

... মরিচা পদ্ধতির প্রায়শই প্রায় দুই ধরণের কেন্দ্রিক:

  • Option, যা এর অনুরূপ std::optional,
  • Result, যা দুটি সম্ভাবনার বৈকল্পিক: ওকে এবং এরর।

এটি অনেক নিকৃষ্ট কারণ সাফল্যের জন্য যাচাই না করে দুর্ঘটনাক্রমে ফলাফল ব্যবহারের কোনও সুযোগ নেই: আপনি যদি করেন তবে প্রোগ্রামটি আতঙ্কিত।


এফপি ভাষাগুলি তাদের ত্রুটি পরিচালনার ক্ষেত্রে ত্রুটি পরিচালনা করে যা তিনটি স্তরে বিভক্ত হতে পারে: - ফান্টেক্টর - প্রয়োগকারী / বিকল্প - মনডস / বিকল্প

আসুন দেখে নেওয়া যাক হাস্কেলের Functorটাইপক্লাস:

class Functor m where
  fmap :: (a -> b) -> m a -> m b

প্রথমত, টাইপক্লাসগুলি কিছুটা অনুরূপ তবে ইন্টারফেসের সমান নয়। হাস্কেলের ফাংশন স্বাক্ষরগুলি প্রথম দেখায় কিছুটা ভীতিজনক দেখাচ্ছে। তবে আসুন সেগুলি বোঝাও। ফাংশনটি fmapপ্রথম প্যারামিটার হিসাবে কোনও ফাংশন নেয় যা কিছুটা অনুরূপ std::function<a,b>। পরের জিনিসটি একটি m a। আপনি mযেমন কিছু std::vectorএবং কিছু হিসাবে কল্পনা m aকরতে পারেন std::vector<a>। তবে পার্থক্যটি হ'ল m aএটি স্পষ্টভাবে বলতে হবে না std:vector। সুতরাং এটিও হতে পারে std::option। ভাষা কহন যে আমরা typeclass জন্য একটি দৃষ্টান্ত করেছে Functorমত একটি নির্দিষ্ট টাইপ জন্য std::vectorঅথবা std::option, আমরা ফাংশন ব্যবহার করতে পারেন fmapযে টাইপ জন্য। টাইপক্ল্যাসগুলির জন্যও একই কাজটি করতে হবে Applicative, AlternativeএবংMonadযা আপনাকে স্টেটফুল, সম্ভাব্য ব্যর্থ গণনা করার অনুমতি দেয়। AlternativeTypeclass কার্যকরী ত্রুটি পুনরুদ্ধারের বিমূর্ত। এর মাধ্যমে আপনি a <|> bএটি অর্থ aবা শব্দ হিসাবে অর্থ মত কিছু বলতে পারেন b। উভয় গণনা দুটিই যদি সফল হয় তবে এটি এখনও একটি ত্রুটি।

আসুন দেখে নেওয়া যাক হাস্কেলের Maybeধরণ সম্পর্কে।

data Maybe a
  = Nothing
  | Just a

এর অর্থ, আপনি যেখানে প্রত্যাশা করেন সেখানে Maybe aআপনি পাবেন Nothingবা পাবেন Just afmapউপরে থেকে তাকানোর সময় , একটি বাস্তবায়ন এর মতো দেখতে পেত

fmap f m = case m of
  Nothing -> Nothing
  Just a -> Just (f a)

case ... ofঅভিব্যক্তি প্যাটার্ন ম্যাচিং এবং বর্ণনার অনুরূপ কি নামে গলি বিশ্বের পরিচিত হয় বলা হয় visitor pattern। রেখাটি case m ofযেমন m.apply(...)এবং বিন্দুগুলি হ'ল প্রেরণের কাজগুলি প্রয়োগ করে এমন কোনও শ্রেণীর ইনস্ট্যান্টেশন। case ... ofঅভিব্যক্তির নীচের লাইনগুলি হ'ল শ্রেণীর ক্ষেত্রগুলি নাম দ্বারা স্কোপগুলিতে সরাসরি আনয়ন সম্পর্কিত প্রেরণ ফাংশন। যে Nothingশাখায় আমরা তৈরি করি Nothingএবং সেই Just aশাখায় আমরা আমাদের একমাত্র মানটির নামকরণ করি aএবং প্রয়োগ করা Just ...ট্রান্সফর্মেশন ফাংশন সহ অন্যটি তৈরি করি । যেমন পড়ুন: ।fanew Just(f(a))

প্রকৃত ত্রুটি চেক দূরে বিমূর্ত করার সময় এটি এখন ভ্রান্ত গণনা পরিচালনা করতে পারে। অন্যান্য ইন্টারফেসের জন্য বাস্তবায়ন রয়েছে যা এই ধরণের কম্পিউটেশনকে খুব শক্তিশালী করে তোলে। আসলে, Maybeমরিচা- Optionটাইপ জন্য অনুপ্রেরণা ।


আমি সেখানে আপনাকে পরিবর্তে আপনার Successক্লাসটি পুনরায় কাজ করতে উত্সাহিত করব Result। আলেকজান্দ্রেস্কু আসলেই কাছাকাছি কিছু প্রস্তাব করেছিল, যার নাম ছিলexpected<T> স্ট্যান্ডার্ড প্রস্তাবনাগুলি ।

আমি মরিচা নামকরণ এবং এপিআই কেবল আটকে থাকব কারণ এটি ডকুমেন্টেড এবং কাজ করে। অবশ্যই, মরিচায় একটি নিফটি ?প্রত্যয় অপারেটর রয়েছে যা কোডটি আরও মধুর করে তোলে; সি ++ এ আমরা TRYম্যাক্রো এবং জিসিসির বিবৃতি প্রকাশটি এটি অনুকরণ করতে ব্যবহার করব ।

template <typename E>
struct Error {
    Error(E e): error(std::move(e)) {}

    E error;
};

template <typename E>
Error<E> error(E e) { return Error<E>(std::move(e)); }

template <typename T, typename E>
struct [[nodiscard]] Result {
    template <typename U>
    Result(U u): ok(true), data(std::move(u)), error() {}

    template <typename F>
    Result(Error<F> f): ok(false), data(), error(std::move(f.error)) {}

    template <typename U, typename F>
    Result(Result<U, F> other):
        ok(other.ok), data(std::move(other.data)),  error(std::move(other.error)) {}

    bool ok = false;
    T data;
    E error;
};

#define TRY(Expr_) \
    ({ auto result = (Expr_); \
       if (!result.ok) { return result; } \
       std::move(result.data); })

দ্রষ্টব্য: Resultএটি একটি স্থানধারক। একটি যথাযথ বাস্তবায়ন এনক্যাপসুলেশন ব্যবহার করবে এবং ক union। পয়েন্টটি পারাপারে এটি পর্যাপ্ত।

যা আমাকে লিখতে দেয় ( এটি ক্রিয়াতে দেখুন ):

Result<double, std::string> sqrt(double x) {
    if (x < 0) {
        return error("sqrt does not accept negative numbers");
    }
    return x;
}

Result<double, std::string> double_sqrt(double x) {
    auto y = TRY(sqrt(x));
    return sqrt(y);
}

যা আমি সত্যিই ঝরঝরে দেখতে পেয়েছি:

  • ত্রুটি কোডগুলি (বা আপনার Successশ্রেণি) ব্যবহারের বিপরীতে ত্রুটিগুলি যাচাই করতে ভুলে গেলে কিছু এলোমেলো আচরণের পরিবর্তে রানটাইম ত্রুটি 1 হবে ,
  • ব্যতিক্রমগুলির ব্যবহারের বিপরীতে, কল সাইটে এটি স্পষ্ট যে কোন ফাংশনগুলি ব্যর্থ হতে পারে তাই এতে কোনও আশ্চর্যের কিছু নেই।
  • সি ++ - 2 এক্স স্ট্যান্ডার্ড সহ আমরা স্ট্যান্ডার্ডে উঠতে পারি concepts। এটি এ ধরণের প্রোগ্রামিংকে আরও বেশি আনন্দদায়ক করে তুলবে কারণ আমরা ত্রুটি ধরণের মাধ্যমে পছন্দটি ছেড়ে যেতে পারি। যেমন std::vectorফলস্বরূপ বাস্তবায়নের সাথে সাথে , আমরা একবারে সমস্ত সম্ভাব্য সমাধানগুলি গণনা করতে পারি। অথবা আপনার প্রস্তাব অনুসারে আমরা ত্রুটি পরিচালনার উন্নতি করতে বেছে নিতে পারি।

1 একটি সঠিকভাবে encapsulated Resultবাস্তবায়ন সঙ্গে;)


দ্রষ্টব্য: ব্যতিক্রম নয়, এই লাইটওয়েটের Resultব্যাকট্রেস নেই, যা লগিংকে কম দক্ষ করে তোলে; আপনি কমপক্ষে ত্রুটি বার্তা উত্পন্ন ফাইল / লাইন নম্বর লগ এবং দরকারী একটি সমৃদ্ধ ত্রুটি বার্তা লিখতে দরকারী মনে হতে পারে। প্রতিবার TRYম্যাক্রো ব্যবহার করা হলে ফাইল / লাইন ক্যাপচার করে এটিকে আরও বাড়ানো যেতে পারে , প্রয়োজনীয়ভাবে ব্যাকট্র্যাসটি ম্যানুয়ালি তৈরি করা বা প্ল্যাটফর্ম-নির্দিষ্ট কোড এবং লাইব্রেরি ব্যবহার করে যেমন libbacktraceকলস্ট্যাকের চিহ্নগুলি তালিকাভুক্ত করে।


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


3
এই ম্যাক্রো দেখতে ... খুব ভুল। আমি ধরে নেব ({...})কিছু জিসিসি এক্সটেনশন, তবে তবুও, এটি হওয়া উচিত নয় if (!result.ok) return result;? আপনার অবস্থা পিছন দিকে প্রদর্শিত হয় এবং আপনি ত্রুটির একটি অপ্রয়োজনীয় অনুলিপি তৈরি করেন।
হাঁস মুচিং

@ মুভিংডাক উত্তরটি ব্যাখ্যা করে যে ({...})এটি জিসিসির বিবৃতি প্রকাশ
জেমসডলিন


1
আপনি যদি সি ++ 17 ব্যবহার করছেন তবে আমি এটি std::variantপ্রয়োগ করতে ব্যবহারের পরামর্শ দেব Result। এছাড়াও, যদি আপনি কোনও ত্রুটি উপেক্ষা করেন তবে একটি সতর্কতা পেতে, ব্যবহার করুন[[nodiscard]]
জাস্টিন

2
@ জাস্টিন: std::variantব্যতিক্রম হ্যান্ডলিংয়ের চারপাশে বাণিজ্য বন্ধ থাকাকালীন ব্যবহার বা না করা কিছুটা স্বাদের বিষয়। [[nodiscard]]আসলেই খাঁটি জয়।
ম্যাথিউ এম।

46

দাবি: ব্যতিক্রমগুলি হ্যান্ডলিংয়ের ত্রুটিগুলির জন্য একটি ভাষা অর্থসূচক

ব্যতিক্রমগুলি একটি নিয়ন্ত্রণ-প্রবাহ প্রক্রিয়া। এই নিয়ন্ত্রণ-প্রবাহের প্রক্রিয়াটির অনুপ্রেরণা, ত্রুটি পরিচালনার ক্ষেত্রে বিশেষত ত্রুটি পরিচালনার কোডটি পৃথকভাবে পৃথক করা ছিল , সাধারণ ক্ষেত্রে যে ত্রুটি পরিচালনা করা খুব পুনরাবৃত্তিযোগ্য এবং যুক্তির মূল অংশটির সাথে সামান্য প্রাসঙ্গিকতা বজায় রাখে।

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

বিবেচনা করুন: আমি একটি ফাইল তৈরি করার চেষ্টা করি। স্টোরেজ ডিভাইসটি পূর্ণ।

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

সুতরাং, আমার প্রোগ্রামটি কি কোনওভাবে কিছু জায়গা খালি করা উচিত এবং তারপরে সাফল্যের সাথে এগিয়ে যেতে হবে, অন্যথায় আমি "সমাধান বিকাশ করতে" খুব অলস? এটাকে স্পষ্টতই অযৌক্তিক মনে হচ্ছে। শেয়ার জমার পরিচালনার জন্য "সমাধান" হয় আমার প্রোগ্রাম আওতার বাইরে , আর আমার প্রোগ্রাম অত্যন্ত শৃঙ্খলার ব্যর্থ এবং হতে পুনরায় রানের ব্যবহারকারী পারেন কিছু জায়গা ছেড়েছে, অথবা কিছু আরো স্টোরেজ যোগ একবার করতে সক্ষম হবেন, হয় জরিমানা


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

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

নির্ভুলতার জন্য - এবং সম্পাদনের জন্য - একবার আপনি কোনও অগ্রগতি করতে না পারলে নিয়ন্ত্রণকে সুযোগের বাইরে ফিরিয়ে দেওয়া আরও ভাল। ব্যতিক্রম এবং সি-স্টাইলের সুস্পষ্ট ত্রুটি প্রথম দিকে ফেরার সাথে পরীক্ষা করে উভয়ই এটি সম্পাদন করে।


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

আমি নিশ্চিত নই যে মোনাদ স্টাইল এবং অলস মূল্যায়ন যদিও সি ++ তে ভাল অনুবাদ করে।


1
আপনার উত্তরের জন্য ধন্যবাদ, এটি বিষয়টিতে আলোক জুড়েছে। আমি অনুমান করি যে যখন ব্যবহারকারী and allowing my program to fail gracefully, and be re-runমাত্র 2 ঘন্টা কাজ হারিয়েছেন তখন তার সাথে একমত হবেন না :
অ্যাড্রিয়ান মায়ার

14
আপনার সমাধান মানে যে যে জায়গা আপনি একটি ফাইল তৈরি করতে পারেন, আপনারা কি পরিস্থিতি এবং পুনরায় চেষ্টা ফিক্স ব্যবহারকারী চটপট করতে হবে। তারপরে অন্য যে কোনও জিনিস ভুল হতে পারে, আপনাকে স্থানীয়ভাবে কোনওভাবে ঠিক করতে হবে। ব্যতিক্রম সহ, আপনি কেবলমাত্র std::exceptionযৌক্তিক অপারেশনের উচ্চ স্তরে ধরা পড়েন, ব্যবহারকারীকে "এক্স। বিট () এর কারণে এক্স ব্যর্থ" বলুন এবং তারা প্রস্তুত থাকলে এবং সম্পূর্ণ প্রস্তুত থাকলে পুনরায় চেষ্টা করার প্রস্তাব দিন offer
বেহুদা

13
@ অ্যাড্রিয়ানমায়ার: "গুপ্তচরভাবে ব্যর্থ হয়ে পুনরায় চালিত হতে দেওয়া" হিসাবেও এটি প্রয়োগ করা যেতে পারে showing the Save dialog again along with an error message and allowing the user to specify an alternative location to try। এটি এমন কোনও সমস্যাটির গ্রেস হ্যান্ডলিং যা সাধারণভাবে কোড থেকে করা যায় না যা সনাক্ত করে যে প্রথম স্টোরেজের অবস্থানটি পূর্ণ।
বার্ট ভ্যান ইনজেন শেনাও

3
রাস্ট, ওসিএএমএল এবং এফ # এর মতো কঠোর মূল্যায়ন ভাষায় প্রমাণিত যে ইউসলেস অলস মূল্যায়নের ত্রুটি মোনাডের ব্যবহারের সাথে কোনও সম্পর্ক নেই, যা সমস্ত এটির ভারী ব্যবহার করে।
বিট্রি

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

15

আমি একটি প্রকল্পে যেমন একটি দৃষ্টান্ত ব্যবহারের প্রভাব আরও ভাল বুঝতে চাই:

  • সমস্যার ভিত্তিটি কি সঠিক? বা আমি কি প্রাসঙ্গিক কিছু মিস করেছি?
  • সমাধানটি কি একটি ভাল স্থাপত্যের ধারণা? নাকি দাম খুব বেশি?

আপনার পদ্ধতির আপনার উত্স কোডে কিছু বড় সমস্যা এনেছে:

  • এটি ক্লায়েন্ট কোডের উপর নির্ভর করে সর্বদা এর মান পরীক্ষা করার জন্য মনে রাখে sত্রুটি পরিচালনার পদ্ধতির জন্য ব্যবহারের রিটার্ন কোডগুলির ক্ষেত্রে এটি সাধারণ এবং ব্যতিক্রমগুলি ভাষাটির মধ্যে প্রবর্তনের কারণগুলির মধ্যে একটি: ব্যর্থতা সহ, যদি আপনি ব্যর্থ হন তবে আপনি নীরবে ব্যর্থ হন না।

  • এই পদ্ধতির সাহায্যে আপনি যত বেশি কোড লিখবেন তত ত্রুটি পরিচালনার জন্য আপনাকে আরও ত্রুটিযুক্ত বয়লারপ্লেট কোড যুক্ত করতে হবে (আপনার কোডটি আর নমনীয় নয়) এবং আপনার রক্ষণাবেক্ষণের প্রচেষ্টাটি এগিয়ে যায়।

তবে বিকাশকারী হিসাবে আমার বেশ কয়েক বছর আমাকে সমস্যাটি একটি ভিন্ন পদ্ধতির থেকে দেখতে দেয়:

প্রযুক্তিগত সীসা স্তর বা দল পর্যায়ে এই সমস্যার সমাধানগুলি যোগাযোগ করা উচিত:

নির্দিষ্ট কেসটি সাবধানতার সাথে প্রয়োগ করা খুব বিরল বলে মনে হয় তখন প্রোগ্রামাররা ব্যতিক্রম ছুঁড়ে দিয়ে তাদের কাজটি সহজ করার প্রবণতা দেখায়। এর সাধারণ বিষয়গুলি হ'ল: মেমরি সমস্যা, ডিস্ক পূর্ণ সমস্যা, দূষিত ফাইল সমস্যা ইত্যাদি This এটি যথেষ্ট হতে পারে তবে স্থির স্তর থেকে সর্বদা সিদ্ধান্ত নেওয়া হয় না।

যদি আপনি নিজেকে সর্বদা ফেলে দেওয়া প্রতিটি ধরণের ব্যতিক্রমগুলি পরিচালনা করে দেখেন তবে নকশাটি ভাল নয়; কী ত্রুটিগুলি পরিচালনা করা হয়, প্রকল্পের নির্দিষ্টকরণ অনুসারে সিদ্ধান্ত নেওয়া উচিত, ডিভস বাস্তবায়নের মতো অনুভূতি অনুসারে নয়।

স্বয়ংক্রিয় পরীক্ষা নিরীক্ষণের মাধ্যমে ইউনিট পরীক্ষার স্পেসিফিকেশন এবং প্রয়োগকরণের পৃথকীকরণের ঠিকানা (দুটি পৃথক পৃথক ব্যক্তিকে এটি করতে হবে) Address

প্রোগ্রামাররা সাবধানতার সাথে ডকুমেন্টেশন পড়ছে না [...] তদ্ব্যতীত, তারা যখন জানে তখনও তারা এগুলি সত্যিই পরিচালনা করে না।

আপনি আরও কোড লিখে এটিকে সম্বোধন করবেন না। আমি মনে করি আপনার সেরা বেটটি সাবধানতার সাথে প্রয়োগ করা কোড পর্যালোচনা।

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

যথাযথ ত্রুটি পরিচালনা করা শক্ত, তবে ফেরতের মানগুলির তুলনায় ব্যতিক্রমগুলি নিয়ে কম ক্লান্তিহীন (তারা আসলে ফিরে আসে বা i / o আর্গুমেন্ট হিসাবে পাস হয়)।

ত্রুটি পরিচালনার সবচেয়ে জটিল অংশটি আপনি কীভাবে ত্রুটিটি পান তা নয়, তবে কীভাবে আপনার অ্যাপ্লিকেশন ত্রুটির উপস্থিতিতে একটি সামঞ্জস্যপূর্ণ অবস্থা রাখে তা নিশ্চিত করে।

এটি সমাধানের জন্য, ত্রুটির অবস্থার (আরও পরীক্ষা, আরও ইউনিট / ইন্টিগ্রেশন পরীক্ষা ইত্যাদি) সনাক্তকরণ এবং চালানোর জন্য আরও মনোযোগ বরাদ্দ করা দরকার।


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

11
না, একটি ব্যতিক্রম পরিচালনা করা (বা ত্রুটি কোডটি ফিরিয়ে দেওয়া) ক্র্যাশ নয় - যদি ত্রুটি / ব্যতিক্রম যুক্তিযুক্তভাবে মারাত্মক না হয় বা আপনি এটি পরিচালনা না করে বেছে নেন। আপনি এখনও আছে সুযোগ , ত্রুটি ক্ষেত্রে পরিচালনা করতে থাকলে কিনা একটি ত্রুটি পূর্বে ঘটেছে স্পষ্টভাবে প্রতিটি পদক্ষেপে চেক করতে থাকার
বেহুদা

11
@ অ্যাড্রিয়ানমায়ার আমি যে প্রায় প্রতিটি অ্যাপ্লিকেশনটিতে কাজ করি সেগুলিতে আমি নিঃশব্দে চালিয়ে যাওয়ার চেয়ে ক্রাশটিকে আরও ব্যাপকভাবে পছন্দ করব। আমি ব্যবসা-সমালোচনামূলক সফ্টওয়্যারটিতে কাজ করি যেখানে কিছু খারাপ আউটপুট নেওয়া এবং এটি চালিয়ে যাওয়া চালিয়ে যাওয়ার ফলে প্রচুর অর্থ হারাতে পারে। যদি সঠিকতা গুরুতর এবং ক্র্যাশযোগ্য গ্রহণযোগ্য হয় তবে ব্যতিক্রমগুলির এখানে খুব বড় সুবিধা রয়েছে।
ক্রিস হেইস

1
@ অ্যাড্রিয়ানমায়ার - আমি মনে করি যে যদি কোনও বিবৃতি ভুলে যাওয়ার আপনার পদ্ধতিটি ব্যতিক্রম করতে হয় তবে তা ভুলে যাওয়া অনেক কঠিন হয়ে যায় ... এছাড়াও - ব্যতিক্রমগুলির মূল সুবিধাটি হ'ল যে স্তরটি তাদের পরিচালনা করে। অ্যাপ্লিকেশন স্তরের ত্রুটি বার্তাটি দেখানোর জন্য আপনি কোনও সিস্টেম ব্যতিক্রমকে আরও বুদ্বুদ করতে দিতে পারেন তবে নিম্ন স্তরে যে পরিস্থিতি সম্পর্কে আপনি জানেন তা পরিচালনা করতে পারেন। আপনি যদি তৃতীয় পক্ষের লাইব্রেরি বা অন্যান্য বিকাশকারী কোড ব্যবহার করে থাকেন তবে এটি সত্যই একমাত্র পছন্দ ...
মিলনি

5
@ অ্যাড্রিয়ান কোনও ভুল নয়, আপনি যা লিখেছেন তা ভুল পড়ে গেছে বলে মনে হচ্ছে বা এর দ্বিতীয়ার্ধটি মিস করেছি। আমার পুরো বিষয়টি এমন নয় যে পরীক্ষার / বিকাশের সময় ব্যতিক্রম ছুঁড়ে ফেলা হবে এবং বিকাশকারীরা বুঝতে পারবেন যে তাদের এগুলি পরিচালনা করা দরকার। মুল বক্তব্যটি হ'ল উত্পাদনে সম্পূর্ণরূপে হাতছাড়া হওয়া ব্যতিক্রমের ফলাফলটি একটি চেক না করা ত্রুটি কোডের ফলাফলের চেয়ে পছন্দসই। আপনি যদি ত্রুটি কোডটি মিস করেন তবে আপনি ভুল ফলাফলগুলি ব্যবহার করতে এবং চালিয়ে যেতে পারেন। আপনি যদি ব্যতিক্রমটি মিস করেন তবে অ্যাপ্লিকেশনটি ক্র্যাশ হয়ে যায় এবং চালিয়ে যাওয়া অব্যাহত রাখে, আপনি কোনও ফলাফল ভুল ফলাফল না পেয়ে পান । (
অবিরত
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.