কেন আমি প্রতিটি ব্লককে "চেষ্টা" - "ধরা" এ মোড়ানো করব না?


430

আমি সর্বদা বিশ্বাস করে এসেছি যে কোনও পদ্ধতি যদি ব্যতিক্রম ছুঁড়ে ফেলতে পারে তবে অর্থবোধক চেষ্টা ব্লক দিয়ে এই কলটি রক্ষা না করা বেপরোয়া।

আমি কেবল পোস্ট করেছি ' আপনার সর্বদা র‌্যাপ কলগুলি চেষ্টা করা উচিত যা ব্লকগুলি ধরতে চেষ্টা করে। ' এই প্রশ্নের কাছে এবং বলা হয়েছিল যে এটি ছিল' উল্লেখযোগ্যভাবে খারাপ পরামর্শ '- কেন তা আমি বুঝতে চাই।


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

উত্তর:


340

কোনও পদ্ধতির কেবল তখনই ব্যতিক্রম ধরা উচিত যখন এটি কিছু বুদ্ধিমান উপায়ে এটি পরিচালনা করতে পারে।

অন্যথায়, কল স্ট্যাকের উচ্চতর কোনও পদ্ধতি এটি উপলব্ধি করতে পারে এই আশায় এটি চালিয়ে যান।

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


12
এটিও লক্ষণীয় যে tryব্লকগুলির জন্য ব্যয় (উত্পন্ন কোডের শর্তাবলী) রয়েছে । স্কট মেয়ার্সের "আরও কার্যকর সি ++" তে একটি ভাল আলোচনা আছে।
নিক মায়ার

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

31
@ ব্লাইন্ডলি: শীর্ষ ব্যতিক্রম হ্যান্ডলারটি ব্যতিক্রমটি পরিচালনা করতে পারে না, তবে প্রকৃতপক্ষে উচ্চস্বরে চিৎকার করে বলা যায় যে সেখানে একটি নিয়ন্ত্রণহীন ব্যতিক্রম ছিল, তার বার্তাটি দিন এবং অনুষ্ঠানটি একটি করুণ উপায়ে শেষ করুন (কল করার পরিবর্তে 1 ফিরে আসুন terminate) । এটি একটি সুরক্ষা ব্যবস্থা বেশি। এছাড়াও, try/catchকোনও ব্যতিক্রম না থাকলে কম বা কম ফ্রি থাকে। যখন কোনও প্রচারকারী থাকে তখন প্রতিটি সময় নিক্ষেপ ও ধরা সময় ব্যয় করে, তাই try/catchকেবলমাত্র পুনর্নবীকরণের একটি চেইন ব্যয়বহুল নয়।
ম্যাথিউ এম।

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

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

136

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

কয়েকটি সম্পর্কিত কোডের গন্ধ রয়েছে যা আপনি অবশ্যই "সর্বত্র সমস্ত কিছু ধরুন" গন্ধ ছাড়াও এড়াতে চান ।

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

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

  3. "ক্যাচ, ক্লিনআপ, রিথ্রো" : এটি আমার পোষা প্রাণীগুলির মধ্যে অন্যতম e আপনি যদি এটির অনেক কিছুই দেখতে পান তবে আপনার উচিত রিসোর্স অ্যাকুইজিশন হ'ল ইনিশিয়ালাইজেশন কৌশলগুলি এবং ক্লিনআপ অংশটি কোনও জিনেটর অবজেক্টের উদাহরণ হিসাবে ধ্বংসকারীতে স্থাপন করা উচিত ।

আমি কোডগুলি পর্যালোচনা এবং রিফ্যাক্টরিংয়ের জন্য ভাল টার্গেট হিসাবে try/ catchব্লকগুলির সাথে লিটারযুক্ত কোড বিবেচনা করি । এটি ইঙ্গিত দেয় যে উভয় ব্যতিক্রম হ্যান্ডলিং ভালভাবে বোঝা যায় না বা কোডটি একটি আম্বা হয়ে গেছে এবং এটি পুনরুদ্ধার করার গুরুতর প্রয়োজন।


6
# 1 আমার কাছে নতুন। তার জন্য +1। এছাড়াও, আমি # 2 এর একটি সাধারণ ব্যতিক্রম নোট করতে চাই, এটি হ'ল যদি আপনি প্রায়শই একটি লাইব্রেরি ডিজাইন করেন তবে আপনি সংযুক্তি হ্রাস করার জন্য আপনার লাইব্রেরি ইন্টারফেসের দ্বারা নির্দিষ্ট কিছুতে অভ্যন্তরীণ ব্যতিক্রমগুলি অনুবাদ করতে চান (এটি আপনার অর্থ হতে পারে "সংঘবদ্ধ সমাধান" দ্বারা, তবে আমি সেই শব্দটির সাথে পরিচিত নই)।
rmeador

3
মূলত আপনি কি বলেন: parashift.com/c++-faq-lite/exceptions.html#faq-17.13
Björn Pollex

1
# 2, যেখানে এটি কোনও কোড-গন্ধ নয় তবে অর্থবোধ তৈরি করে, পুরানো ব্যতিক্রমটিকে নেস্টেড হিসাবে রেখে বাড়ানো যেতে পারে।
উত্সাহক

1
# 1 সম্পর্কিত: std :: uncaught_exception () আপনাকে বলেছে যে ফ্লাইটে একটি অপ্রকাশিত ব্যতিক্রম রয়েছে, কিন্তু আফাইক কেবল একটি ক্যাচ () ধারা আপনাকে সেই ব্যতিক্রমটি আসলে কী তা নির্ধারণ করতে দেয়। সুতরাং আপনি যখন অবিচ্ছিন্ন ব্যতিক্রমের কারণে আপনি সুযোগ থেকে বেরিয়ে এসেছেন এই সত্যটি লগ করতে পারছেন, কেবল একটি বদ্ধ চেষ্টা / ক্যাচ আপনাকে কোনও বিবরণ লগ করতে দেয়। সঠিক?
জেরেমি

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

48

কারণ পরবর্তী প্রশ্নটি "আমি একটি ব্যতিক্রম ধরা পড়েছি, এর পরে আমি কী করব?" তুমি কি করবে? যদি আপনি কিছু না করেন - এটি লুকিয়ে থাকা ত্রুটি এবং প্রোগ্রামটি ঘটেছে তা আবিষ্কার করার কোনও সুযোগ ছাড়াই "ঠিক কাজ করতে পারে না"। আপনি ব্যতিক্রম ধরা পরে একবার আপনি ঠিক কি করবেন বুঝতে হবে এবং কেবল যদি আপনি জানেন তবে ধরা।


29

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

এটি তিনটি কারণে দুর্দান্ত: এটি কার্যকর কারণ আপনার ত্রুটির প্রতিবেদন করার জন্য একক জায়গা রয়েছে: SaveDocument()ক্যাচ ব্লক (গুলি)। সমস্ত উপ-পদ্ধতিতে এটির পুনরাবৃত্তি করার দরকার নেই এবং আপনি যেভাবেই এটি চান: কোনওটি ভুল হয়ে গেছে সে সম্পর্কে ব্যবহারকারীকে একটি কার্যকর ডায়াগনস্টিক দেওয়ার জন্য একটি একক জায়গা।

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

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

int ret = SaveFirstSection();

if (ret == FAILED)
{
    /* some diagnostic */
    return;
}

ret = SaveSecondSection();

if (ret == FAILED)
{
    /* some diagnostic */
    return;
}

ret = SaveThirdSection();

if (ret == FAILED)
{
    /* some diagnostic */
    return;
}

এখানে কীভাবে ব্যাতিক্রম লেখা যেতে পারে:

// these throw if failed, caught in SaveDocument's catch
SaveFirstSection();
SaveSecondSection();
SaveThirdSection();

এখন যা ঘটছে তা অনেক পরিষ্কার।

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


2
দুর্দান্ত উদাহরণ। হ্যাঁ, লজিক ইউনিটগুলিতে যেমন যথাসম্ভব উঁচুতে ধরুন যেমন লোড / সেভ / ইত্যাদির মতো কিছু 'ট্রানজেকশনাল' অপারেশন রয়েছে। কোড পুনরাবৃত্তিমূলক, অপ্রয়োজনীয় try- catchব্লকগুলির সাথে কিছুটা খারাপ দেখায় না যা কিছু ভুল বার্তার সাথে কিছু ত্রুটির প্রতিটি সামান্য পৃথক ক্রিয়াকলাপকে পতাকাঙ্কিত করার চেষ্টা করে, বাস্তবে যখন তাদের সকলের একই পরিণতি ঘটে: লেনদেন বা প্রোগ্রাম ব্যর্থতা এবং প্রস্থান! যদি কোনও ব্যতিক্রম-যোগ্য ব্যর্থতা দেখা দেয় তবে আমি বেশিরভাগ ব্যবহারকারীই ঠিক করতে পারি যে তারা যা করতে পারে তা উদ্ধার করতে পারে বা কমপক্ষে, এটি সম্পর্কে 10 টি বার্তার বার্তা না নিয়েই একা থাকতে পারে।
আন্ডারস্কোর_

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

27

ভেষজ সুটার এখানে এই সমস্যা সম্পর্কে লিখেছেন । পড়ার জন্য নিশ্চিত।
একটি টিজার:

"ব্যতিক্রম-নিরাপদ কোড লেখাই মূলত সঠিক জায়গায় 'চেষ্টা' এবং 'ধরা' লেখার বিষয়ে। আলোচনা করা.

কথায় কথায় বলতে গেলে, এই বিবৃতি ব্যতিক্রম সুরক্ষার একটি মৌলিক ভুল বোঝাবুঝির প্রতিফলন করে। ব্যতিক্রমগুলি ত্রুটি প্রতিবেদন করার অন্য একটি রূপ, এবং আমরা অবশ্যই জানি যে ত্রুটি-নিরাপদ কোড লেখার ক্ষেত্রে কেবল ফিরে আসা কোডগুলি পরীক্ষা করা এবং ত্রুটির শর্তাদি পরিচালনা করতে হবে তা নয়।

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


15

অন্যান্য উত্তরে যেমন বলা হয়েছে, আপনি যদি কেবল এর জন্য কিছুটা বুদ্ধিমান ত্রুটি হ্যান্ডলিং করতে পারেন তবে আপনার কেবল ব্যতিক্রম ধরা উচিত।

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


12

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

ব্যতিক্রমগুলির পুরো বিষয়টিটি হ'ল কল চেইনে প্রতিটি পদ্ধতিতে এগুলি হ্যান্ডেল করার দরকার নেই।


9

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


2
@ কিথবি: আমি এটিকে দ্বিতীয়-সেরা কৌশল হিসাবে বিবেচনা করব। লগটি অন্যভাবে লেখা পেতে পারলে ভাল।
ডেভিড থর্নলি

1
@ কিথবি: কৌশলটি "লাইব্রেরিতে কিছুই নয় তার চেয়ে ভাল" কৌশল। "ধরুন, লগ করুন, এটির সাথে সঠিকভাবে মোকাবিলা করুন" যেখানে সম্ভব সেখানে আরও ভাল। (হ্যাঁ, আমি জানি এটি সবসময় সম্ভব নয়))
ডোনাল ফেলো

6

আমি নীচের স্তরে যথাসম্ভব ব্যতিক্রম পরিচালনা করতে আপনার প্রশ্নের মূল দিকের সাথে একমত।

বিদ্যমান কয়েকটি উত্তর যেমন "আপনার ব্যতিক্রম হ্যান্ডেল করার দরকার নেই। অন্য কেউ স্ট্যাকটি সম্পন্ন করবেন" " আমার অভিজ্ঞতার কাছে এটি বর্তমানে বিকশিত কোডের কিছু অংশে ব্যতিক্রম হ্যান্ডেলিং সম্পর্কে চিন্তা না করার জন্য একটি খারাপ অজুহাত , ব্যতিক্রমটি অন্য কারও বা পরে সমস্যাটিকে পরিচালনা করে making

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


5

আমার কম্পিউটার বিজ্ঞান প্রফেসর আমাকে একবার যে পরামর্শ দিয়েছিলেন তা হ'ল: "চেষ্টা করুন এবং ক্যাচ ব্লকগুলি তখনই ব্যবহার করুন যখন মানক উপায় ব্যবহার করে ত্রুটিটি পরিচালনা করা সম্ভব হয় না।"

উদাহরণস্বরূপ, তিনি আমাদের বলেছিলেন যে কোনও প্রোগ্রাম যদি এমন কোনও জায়গায় গুরুতর সমস্যার সমাধান করে যেখানে এমন কিছু করা সম্ভব হয় না:

int f()
{
    // Do stuff

    if (condition == false)
        return -1;
    return 0;
}

int condition = f();

if (f != 0)
{
    // handle error
}

তারপরে আপনার চেষ্টা করা উচিত, ব্লক ধরুন। আপনি যখন এটি পরিচালনা করতে ব্যতিক্রমগুলি ব্যবহার করতে পারেন তবে এটি সাধারণত সুপারিশ করা হয় না কারণ ব্যতিক্রমগুলি ব্যয়বহুল কর্মক্ষমতা অনুযায়ী wise


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

1
-1 @ সেজেলিকা আপনার উত্তরটি ব্যতিক্রম এড়ানোর সাথে জড়িত, তাই চেষ্টা করার দরকার নেই।
ভিসেন্টে বোটেট এসক্রিবা

3
@ ক্রিস্টোফার: রিটার্ন কোডের অন্যান্য বড় অসুবিধাগুলি হ'ল রিটার্ন কোডটি চেক করতে ভুলে যাওয়া আসল সহজ, এবং কল করার পরে সমস্যাটি হ্যান্ডেল করার পক্ষে সর্বোত্তম জায়গা নয়।
ডেভিড থর্নলি

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

3

আপনি যদি প্রতিটি কার্যের ফলাফল পরীক্ষা করতে চান তবে রিটার্ন কোডগুলি ব্যবহার করুন।

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

ভাল নকশাযুক্ত কোডে আরও গভীর ফাংশন নিক্ষেপ করতে পারে এবং উচ্চতর ফাংশনগুলি ধরে ফেলতে পারে। তবে মূলটি হ'ল "এর মাঝে" অনেকগুলি ফাংশন ব্যতিক্রমী শর্তগুলি হ্যান্ডল করার ভার থেকে মুক্ত হবে। তাদের কেবল "ব্যতিক্রম নিরাপদ" হতে হবে, যার অর্থ এই নয় যে তারা অবশ্যই ধরবে।


2

আমি এই আলোচনায় যুক্ত করতে চাই যে, সি ++ 11 সাল থেকে এটি অনেকটা অর্থবোধ করে, যতক্ষণ না প্রতিটি catchব্লক rethrowব্যতিক্রম হয় যতক্ষণ না পয়েন্ট পর্যন্ত এটি পরিচালনা করা উচিত। এইভাবে একটি ব্যাকট্র্যাস উত্পন্ন করা যেতে পারে । অতএব আমি বিশ্বাস করি পূর্ববর্তী মতামত আংশিক পুরানো।

ব্যবহার করুন std::nested_exceptionএবংstd::throw_with_nested

এটি স্ট্যাকওভারফ্লোতে এবং এখানে কীভাবে এটি অর্জন করা যায় সে সম্পর্কে বর্ণনা করা হয়েছে

যেহেতু আপনি যে কোনও উদ্ভূত ব্যতিক্রম শ্রেণীর সাহায্যে এটি করতে পারেন, আপনি এই জাতীয় ব্যাকট্রাসে প্রচুর তথ্য যুক্ত করতে পারেন! আপনি গিটহাবের আমার এমডব্লিউইতে একবার দেখে নিতে পারেন , যেখানে ব্যাকট্রিসটি এরকম কিছু দেখায়:

Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"

2

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

আমার দলটি ইউআই-তে উল্লেখযোগ্য পরিবর্তন না করে কীভাবে সমস্যাগুলি সমাধান করেছিল? সরল, প্রতিটি পদ্ধতি চেষ্টা করে চালিত হয়েছিল .c এবং সংস্করণ। এই তথ্যের সাহায্যে বিকাশকারীরা সবচেয়ে বেশি ব্যতিক্রম সনাক্ত করতে ত্রুটিগুলির উপর বিশ্লেষণ চালাতে পারে! অথবা সর্বাধিক সংখ্যক ত্রুটিযুক্ত নামস্থান। এটি বৈধতাও দিতে পারে যে মডিউলটিতে ঘটে যাওয়া একটি ত্রুটি সঠিকভাবে পরিচালনা করা হয়েছে এবং একাধিক কারণে নয়।

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

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

এই পদ্ধতির সাহায্যে ডিভগুলিকে উত্পাদনে অন্তর্বর্তী সমস্যাগুলি সন্ধান করতে এবং ঠিক করতে দেয়! আপনি কি প্রযোজনায় কোনও ডিবাগার ছাড়াই ডিবাগ করতে চান? অথবা আপনি বরং কল নেবেন এবং বিরক্ত ব্যবহারকারীদের ইমেল পাবেন? সমস্যা সমাধানের জন্য প্রয়োজনীয় সবকিছু ঠিক আছে বলে অন্য কেউ জানেন না এবং ইমেল, আইএম, বা স্ল্যাক সমর্থন না করেই এটি আপনাকে সমস্যার সমাধান করতে দেয়। 95% ইস্যুগুলির কখনই পুনরুত্পাদন করা প্রয়োজন।

সঠিকভাবে কাজ করার জন্য এটি সেন্ট্রালাইজড লগিংয়ের সাথে একত্রীকরণ করা দরকার যা নেমস্পেস / মডিউল, শ্রেণীর নাম, পদ্ধতি, ইনপুট এবং ত্রুটির বার্তা এবং একটি ডাটাবেসে সঞ্চয় করতে পারে যাতে কোন পদ্ধতিটি সবচেয়ে বেশি ব্যর্থ হয় তাই হাইলাইট করার জন্য এটি একত্রিত করা যায় যাতে এটি হতে পারে প্রথম স্থির।

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

এই প্রযুক্তিটি এমন অ্যাপ্লিকেশনটি দ্রুত স্থিতিশীল করতে ব্যবহৃত হয়েছিল যা 2 বছরেরও বেশি সময় ধরে 12 দেবগণ দ্বারা নির্মিত একটি ফরচুন 500 কোম্পানির বেশিরভাগ ব্যবহারকারীদের জন্য প্রতি ঘন্টা ব্যর্থ হয়। এটি ব্যবহার করে 3000 বিভিন্ন ব্যতিক্রম চিহ্নিত করা হয়েছিল, স্থির, পরীক্ষা করা হয়েছিল এবং 4 মাসের মধ্যে স্থাপন করা হয়েছিল। এটি গড়ে 4 মাসের জন্য প্রতি 15 মিনিটে স্থির হয়ে যায়।

আমি সম্মত হয়েছি যে কোডটি ইনস্ট্রুমেন্ট করার জন্য প্রয়োজনীয় সমস্ত কিছু টাইপ করা মজাদার নয় এবং আমি পুনরাবৃত্তি কোডটি না দেখাই পছন্দ করি, তবে প্রতিটি পদ্ধতিতে 4 টি লাইন কোড যুক্ত করা দীর্ঘমেয়াদী উপযুক্ত।


1
প্রতিটি ব্লক মোড়ানো ওভারকিলের মতো মনে হয়। এটি আপনার কোডটি দ্রুত ফোটানো এবং পড়ার জন্য বেদনাদায়ক করে তোলে। উচ্চ স্তরে একটি ব্যতিক্রম থেকে স্ট্যাকট্রেস লগইন করে আপনি দেখান যে সমস্যাটি কোথায় ঘটেছে এবং ত্রুটির সাথে মিলিত হওয়া সাধারণত সাধারণত যথেষ্ট তথ্য রয়েছে। আমি কৌতূহল করব যেখানে আপনি এটি যথেষ্ট না পেয়ে পেলেন। ঠিক তাই আমি অন্য কারও অভিজ্ঞতা অর্জন করতে পারি।
ব্যবহারকারী 441521

1
"ব্যতিক্রমগুলি স্বাভাবিক কোডের চেয়ে 100 থেকে 1000 গুণ কম ধীরে ধীরে এবং পুনরায় পুনর্বিবেচনা করা উচিত নয়" - বেশিরভাগ আধুনিক সংকলক এবং হার্ডওয়্যারে উক্ত বিবৃতিটি সত্য নয়।
মিচ গম

এটি ওভারকিলের মতো বলে মনে হয় এবং এতে কিছুটা টাইপিংয়ের প্রয়োজন হয় তবে উত্পাদনের মাঝে মাঝে ত্রুটি সহ প্রথম বৃহত্তম ত্রুটিগুলি খুঁজে বের করার এবং সমাধানের ব্যতিক্রমগুলি বিশ্লেষণ করার একমাত্র উপায়। ক্যাচ ব্লক যদি প্রয়োজন হয় তবে নির্দিষ্ট ত্রুটিগুলি পরিচালনা করে এবং কোডের একক লাইন থাকে যা লগ করে।
ব্যবহারকারী2502917

না, ব্যতিক্রমগুলি খুব ধীর। বিকল্পটি হল রিটার্ন কোড, অবজেক্টস বা ভেরিয়েবল। এই স্ট্যাক ওভারফ্লো পোস্টটি দেখুন ... "ব্যতিক্রমগুলি রিটার্ন কোডগুলির চেয়ে কমপক্ষে 30,000 গুণ কম ধীরে ধীরে" stackoverflow.com/questions/891217/…
user2502917

1

উপরের পরামর্শ ছাড়াও, ব্যক্তিগতভাবে আমি কিছু চেষ্টা + ধরা + থ্রো ব্যবহার করি; নিম্নলিখিত কারণে:

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

1

আমি অন্য উত্তর যুক্ত করতে বাধ্য বোধ করি যদিও মাইক গমের উত্তরটি মূল পয়েন্টগুলি বেশ ভালভাবে তুলে ধরেছে। আমি এটি এর মত মনে করি। যখন আপনার কাছে এমন একাধিক কাজ করার পদ্ধতি রয়েছে যখন আপনি জটিলতা বাড়িয়ে তুলছেন, এটি যুক্ত করবেন না।

অন্য কথায়, একটি পদ্ধতির যা চেষ্টা করে ধরা পড়ে তার দুটি সম্ভাব্য ফলাফল রয়েছে। আপনার অ-ব্যতিক্রম ফলাফল এবং ব্যতিক্রম ফলাফল রয়েছে। আপনি যখন প্রচুর পদ্ধতি ব্যবহার করছেন তখন এই তাত্পর্যপূর্ণভাবে বোঝা ছাড়িয়ে যায় compre

তাত্পর্যপূর্ণ কারণ যদি প্রতিটি পদ্ধতি দুটি ভিন্ন উপায়ে শাখা করে থাকে তবে প্রতিবার আপনি অন্য পদ্ধতিটি কল করার সময় আপনি পূর্ববর্তী সংখ্যার সম্ভাব্য ফলাফলগুলির স্কোয়ার করছেন। আপনি পাঁচটি পদ্ধতি কল করার সময় আপনি ন্যূনতম সময়ে 256 টি সম্ভাব্য ফলাফল পর্যন্ত রয়েছেন। প্রতিটি একক পদ্ধতিতে চেষ্টা / ক্যাপচার না করার সাথে এটি তুলনা করুন এবং আপনার অনুসরণ করার জন্য কেবল একটি পথ রয়েছে।

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

সুতরাং সংক্ষেপে, চেষ্টা / ক্যাচগুলি কোড বোঝা আরও শক্ত করে তোলে।


-2

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

  1. আপনি এই ব্লকটি ব্যবহার করতে পারেন যেখানে আপনি একটি ব্যতিক্রম পরিচালনা করতে চান বা কেবল আপনি বলতে পারেন যে লিখিত কোডের ব্লকটি একটি ব্যতিক্রম ছুঁড়ে দিতে পারে।
  2. যদি আপনি আপনার অবজেক্টগুলি ব্যবহারের সাথে সাথে তা নিষ্পত্তি করতে চান তবে আপনি try-catchব্লকটি ব্যবহার করতে পারেন ।

1
"আপনি যদি নিজের জিনিসগুলির ব্যবহারের সাথে সাথে তা নিষ্পত্তি করতে চান তবে আপনি ট্রাই-ক্যাচ ব্লক ব্যবহার করতে পারেন।" আপনি কী এই পরিকল্পনাটি RAII / ন্যূনতম অবজেক্টের আজীবন প্রচার করতে চান? যদি তা হয় তবে ভাল, try/ catchএটি থেকে সম্পূর্ণ আলাদা / অরথোগোনাল। যদি আপনি কোনও ছোট স্কোপে অবজেক্টগুলি নিষ্পত্তি করতে চান তবে আপনি কেবল একটি নতুন খুলতে পারেন { Block likeThis; /* <- that object is destroyed here -> */ }- অবশ্যই এটির মধ্যে try/ মোড়ানো catchদরকার catchনেই, অবশ্যই যদি আপনার কিছু দরকার হয় না , অবশ্যই।
আন্ডারস্কোর_

# 2 - ব্যতিক্রমগুলিতে অবজেক্টগুলি (যা ম্যানুয়ালি তৈরি করা হয়েছিল) নিষ্পত্তি করা আমার কাছে অদ্ভুত বলে মনে হয়, এটি কোনও ভাষায় কোনও সন্দেহ নেই, তবে সাধারণত আপনি এটি চেষ্টা / শেষ পর্যন্ত "চেষ্টাটির মধ্যে / ব্লক ব্যতীত" করেন এবং না বিশেষত ব্যতীত নিজেই বাদে - যেহেতু বস্তুটি নিজেই প্রথম স্থানে ব্যতিক্রমের কারণ হতে পারে এবং এইভাবে অন্য একটি ব্যতিক্রম ঘটায় এবং সম্ভাব্যভাবে একটি ক্র্যাশ ঘটায়।
টিএস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.