কেন সি # তে একটি ব্যতিক্রম ধরা এবং পুনর্বিবেচনা করবেন?


557

আমি সিরিয়ালটিজযোগ্য ডিটিও-তে ডেটা ট্রান্সফার অবজেক্ট সি # নিবন্ধটি দেখছি।

নিবন্ধটিতে কোডের এই অংশটি অন্তর্ভুক্ত রয়েছে:

public static string SerializeDTO(DTO dto) {
    try {
        XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
        StringWriter sWriter = new StringWriter();
        xmlSer.Serialize(sWriter, dto);
        return sWriter.ToString();
    }
    catch(Exception ex) {
        throw ex;
    }
}

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

অতএব:

public static string SerializeDTO(DTO dto) {
    XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
    StringWriter sWriter = new StringWriter();
    xmlSer.Serialize(sWriter, dto);
    return sWriter.ToString();
}

অথবা আমি সি # তে ত্রুটি পরিচালনার বিষয়ে মৌলিক কিছু অনুভব করছি? এটি জাভা (মাইনাস চেক ব্যতিক্রমগুলি) এর মতোই বেশ, তাই না? ... এটি উভয়ই সি ++ পরিমার্জন করেছে।

স্ট্যাক ওভারফ্লো প্রশ্ন পুনরায় নিক্ষেপণ প্যারামিটার-কম ধরা এবং কিছু না করার মধ্যে পার্থক্য? আমার বিতর্কটি সমর্থন করে বলে মনে হচ্ছে যে চেষ্টা করা-থ্রো-হ'ল একটি অপশন।


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

ভবিষ্যতে যে কেউ এই থ্রেডটি খুঁজে পান তার সংক্ষিপ্তসার হিসাবে ...

করো না

try {
    // Do stuff that might throw an exception
}
catch (Exception e) {
    throw e; // This destroys the strack trace information!
}

স্ট্যাক ট্রেস তথ্য সমস্যার মূল কারণ সনাক্ত করতে গুরুত্বপূর্ণ হতে পারে!

আপনি কি

try {
    // Do stuff that might throw an exception
}
catch (SqlException e) {
    // Log it
    if (e.ErrorCode != NO_ROW_ERROR) { // filter out NoDataFound.
        // Do special cleanup, like maybe closing the "dirty" database connection.
        throw; // This preserves the stack trace
    }
}
catch (IOException e) {
    // Log it
    throw;
}
catch (Exception e) {
    // Log it
    throw new DAOException("Excrement occurred", e); // wrapped & chained exceptions (just like java).
}
finally {
    // Normal clean goes here (like closing open files).
}

কম সুনির্দিষ্ট (জাভা যেমন) এর আগে আরও নির্দিষ্ট ব্যতিক্রমগুলি ধরুন C


তথ্যসূত্র:


8
ভাল সংক্ষিপ্তসার; শেষ অবধি অন্তর্ভুক্ত জন্য অতিরিক্ত পয়েন্ট।
ফ্রেডরিক মের্ক

আমি যুক্ত করতে চাই আপনি "নিক্ষেপ" ব্যবহার করতে পারেন "নিক্ষেপ" এর আগে e.Data সংগ্রহের পদ্ধতিতে পাঠানো পরামিতিগুলি যুক্ত করে আরও বেশি সহায়ক হতে হবে; বিবৃতি
মাইকেল বাহীগ

@ মিক দ্য ওয়ার্মচাইন ডিজাইনার (এবং খণ্ডকালীন চিত্রশিল্পী) তাই না? আপনি মাইক্রোসাইট সাকওয়েল (সম্ভবত 2005 এর পরে, আমি জানি সকলের জন্য) ব্যতিক্রমগুলি পরিচালনা করার কথা বলছি। আমি সাধারণভাবে ব্যতিক্রম হ্যান্ডলিংয়ের কথা বলছিলাম। এবং হ্যাঁ, আমি প্রায় চার বছর আগে এই পোস্ট করার পরে আমি কিছু শিখেছি .... তবে হ্যাঁ, আমি স্বীকার করি যে আপনার বৈধ পয়েন্ট রয়েছে, তবে আমার মনে হয় আপনি আসল পয়েন্টটি মিস করেছেন; তুমি যদি আমার প্রবাহ পেয়েছ? এই প্রশ্নটি সি # তে জেনারালাইজড ব্যতিক্রম হ্যান্ডলিং সম্পর্কে; এবং আরও বিশেষভাবে সমস্ত ধরণের ব্যতিক্রমগুলি সম্পর্কে পুনর্বিবেচনা সম্পর্কে। Cool?
Corlettk

দয়া করে আপনার প্রশ্নের সম্পাদনার সংক্ষিপ্ত বিভাগটি তার নিজের উত্তরে নিয়ে যাওয়া বিবেচনা করুন। কেন, দেখুন প্রশ্ন আউট স্ব-উত্তর সম্পাদনা করা এবং প্রশ্ন এমবেড উত্তরঃ
ডেভিডআরআর

2
"মলদ্বার ঘটেছিল" অংশটি কি কেউ লক্ষ্য করেনি? দেখে মনে হচ্ছে কোডটি পুপের জন্য চলে গেছে!
জেসন লোকি স্মিথ

উত্তর:


430

প্রথম; নিবন্ধের কোডটি যেভাবে করে তা মন্দ। throw exএই স্ট্র স্টেটমেন্টটি যেখানে রয়েছে সেখানে ব্যতিরেকে কল স্ট্যাকটিকে পুনরায় সেট করবে; ব্যতিক্রমটি আসলে কোথায় তৈরি হয়েছিল সে সম্পর্কে তথ্য হারাচ্ছেন।

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

যাইহোক, এমন কিছু ঘটনা রয়েছে যেখানে আপনি ব্যতিক্রমটি ধরতে এবং পুনরায় পাঠাতে চাইতে পারেন। লগিং তাদের মধ্যে একটি হতে পারে:

try 
{
    // code that may throw exceptions    
}
catch(Exception ex) 
{
    // add error logging here
    throw;
}

6
@ ফ্রেড্রিক, শুধু ফাই (যদি আপনি সম্ভবত জানেন) আপনি যদি সেই exবস্তুটি ব্যবহার না করে থাকেন তবে তা তাত্ক্ষণিকভাবে চালানোর দরকার নেই।
ইয়োন ক্যাম্পবেল

78
@ ইইন: এটি ইনস্ট্যান্ট না হলে এটি লগ করা বরং কঠিন হবে।
স্যাম অ্যাক্স

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

4
জাভাতেও কি এটি সত্য ... "নিক্ষেপ" বনাম "থ্রো প্রাক্তন"?
জেসনস্টল্টজ

8
@ জেসন, এই প্রশ্নটি দেখুন । জাভাতে, throw exস্ট্যাকট্রেস পুনরায় আরম্ভ করবেন না।
ম্যাথু ফ্ল্যাশেন

117

এটা করবেন না,

try 
{
...
}
catch(Exception ex)
{
   throw ex;
}

আপনি স্ট্যাক ট্রেস তথ্য হারাবেন ...

হয় না,

try { ... }
catch { throw; }

অথবা

try { ... }
catch (Exception ex)
{
    throw new Exception("My Custom Error Message", ex);
}

আপনি যদি নতুন ব্যতিক্রমগুলি পরিচালনা করছেন, উদাহরণস্বরূপ, আপনি পুনর্বিবেচনা করতে চান তার একটি কারণ

try
{
   ...
}
catch(SQLException sex)
{
   //Do Custom Logging 
   //Don't throw exception - swallow it here
}
catch(OtherException oex)
{
   //Do something else
   throw new WrappedException("Other Exception occured");
}
catch
{
   System.Diagnostics.Debug.WriteLine("Eeep! an error, not to worry, will be handled higher up the call stack");
   throw; //Chuck everything else back up the stack
}

7
কেন পুরোপুরি ধরা {নিক্ষেপ leave ছাড়বেন না?
অ্যান্থনিডব্লু জোনস

3
ক্যাচ ছাড়ার এখনও মূল্য আছে {নিক্ষেপ; exception ভিত্তিতে নির্দিষ্ট ব্যতিক্রম ধরণের ক্যাচের তালিকার নীচে এটি প্রমাণ করে যে লেখক মামলাটি বিবেচনা করেছেন, যদিও কোনও মন্তব্য সমানভাবেই যথেষ্ট। আপনি কোড পড়বেন তখন অনুমান করা ভাল জিনিস is
অনাকাটা

87
কোনও কারণে, এসকিউএলএক্সসেপশন নামটি আমাকে বিরক্ত করে।
মাইকেল ম্যাইইয়ার্স

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

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

56

সি # (সি # 6 এর আগে) সিআইএল "ফিল্টার করা ব্যতিক্রমগুলি" সমর্থন করে না, যা ভিবি করে, তাই সি # 1-5-এ একটি ব্যতিক্রম পুনরায় নিক্ষেপের একটি কারণ হ'ল ক্যাচের সময় আপনার কাছে পর্যাপ্ত তথ্য নেই () আপনি আসলে ব্যতিক্রমটি ধরতে চেয়েছিলেন কিনা তা নির্ধারণ করার জন্য।

উদাহরণস্বরূপ, ভিবিতে আপনি করতে পারেন

Try
 ..
Catch Ex As MyException When Ex.ErrorCode = 123
 .. 
End Try

... যা বিভিন্ন ত্রুটি কোডের মানগুলির সাথে মাইএক্সেপশনগুলি পরিচালনা করবে না। ভি # এর আগে সি # তে, ত্রুটি কোড 123 না হলে আপনাকে মাই এক্সেপশনটি ধরে ফেলতে হবে এবং পুনরায় নিক্ষেপ করতে হবে:

try 
{
   ...
}
catch(MyException ex)
{
    if (ex.ErrorCode != 123) throw;
    ...
}

যেহেতু সি # 6.0 আপনি ভিবি'র মতো ফিল্টার করতে পারেন :

try 
{
  // Do stuff
} 
catch (Exception e) when (e.ErrorCode == 123456) // filter
{
  // Handle, other exceptions will be left alone and bubble up
}

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

1
ঠিক আছে, প্রশ্নটি হল "কেন সি # তে ব্যতিক্রম ধরা এবং পুনর্বার কেন?" এবং এটি একটি উত্তর। =] ... এমনকি বিশেষ ব্যতিক্রমগুলির সাথেও ব্যাতিক্রমের ফিল্টারগুলি বোধগম্য: আপনি যেখানে রয়েছেন সেই ক্ষেত্রে বিবেচনা করুন, আসুন একটি স্কাইলটাইমআউটপ্লেশন এবং একটি স্কেল কানেকশন রিসেট এক্সেকশন হ্যান্ডলিংয়ের বিষয়টি বিবেচনা করুন, যা উভয়ই স্কেলএক্সসেপশন। ব্যতিক্রম ফিল্টারগুলি যখন এই দুটির মধ্যে একটির ক্ষেত্রেই কেবল একটি স্কেলএক্সসেপশন ধরতে দেয়, সুতরাং আপনার এই চেষ্টাটির জন্য এই দুটির জন্য অভিন্ন হ্যান্ডলিংয়ের সাথে ঝাঁকুনির পরিবর্তে আপনি "SqlException প্রাক্তন যখন SqlTimeoutException বা প্রাক্তন SqlConnicationResetException" হিসাবে ধরতে পারেন "। (আমি ডেভ
বিটিডব্লু

3
ফিল্টার ব্যতিক্রমগুলি সি # 6 এ আসছে!
স্যার ক্রিসপলট

14

কোড থাকার মতো আমার মূল কারণ:

try
{
    //Some code
}
catch (Exception e)
{
    throw;
}

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

যদিও এটি ডিবাগ করার সময় তারা দুর্দান্ত।


1
হ্যাঁ, আমি এটি পরিশোধ করব, তবে হ্যাঁ, আপনি এটি প্রকাশিত কোডে দেখতে চান না ... কারণ: এটি প্রকাশে আমি লজ্জা
পাব

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

8
আপনি যদি ডিবাগিংয়ের সময় কেবলমাত্র কিছু কোড ব্যবহার করতে চান তবে #if DEBUG ... #endif ব্যবহার করুন এবং আপনার এই লাইনগুলি সরাতে হবে না
মাইকেল ফ্রেইজিম

1
হ্যাঁ, আমি নিজে কয়েকবার করেছি। প্রতি এখন এবং পরে একটি মুক্তি পেতে পালাতে হবে। @ জ্যামাইকেকস ব্যতিক্রম ভিজ্যুয়াল স্টুডিওর বিরতিতে সমস্যাটি হ'ল, কখনও কখনও আমি যে ব্যতিক্রম চাই তা কেবল একমাত্র (বা এমনকি তার ধরণের একমাত্র) নিক্ষেপ করা হয় না। "ব্যতিক্রম বাদে ব্রেক হলে" সহ একটি ব্রেক পয়েন্ট শর্ত সম্পর্কে এখনও জানেন না। ততক্ষণে, এটি কার্যকর থাকবে। মাইকেল ফ্রিজিম: দু'জনের #if DEBUGকাছাকাছি try {এবং } catch () {...}কিছুটা অগোছালো এবং খোলামেলাভাবে আমাকে উদ্বিগ্ন করে তোলে ... প্রাক-প্রসেসরটি সাধারণত বলছেন, আমার বন্ধু নয়।

11

ব্যতিক্রমগুলি পুনর্বিবেচনার একটি বৈধ কারণ হ'ল আপনি ব্যতিক্রমটিতে তথ্য যুক্ত করতে চান, বা সম্ভবত নিজের কোনও তৈরিতে মূল ব্যতিক্রমটি মুড়ে রাখতে চান:

public static string SerializeDTO(DTO dto) {
  try {
      XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
      StringWriter sWriter = new StringWriter();
      xmlSer.Serialize(sWriter, dto);
      return sWriter.ToString();
  }
  catch(Exception ex) {
    string message = 
      String.Format("Something went wrong serializing DTO {0}", DTO);
    throw new MyLibraryException(message, ex);
  }
}

থ্যাঙ্কস, হ্যাঁ ব্যতিক্রমী মোড়ানো (বিশেষত শৃঙ্খলাবদ্ধ) পুরোপুরি বুদ্ধিমান ... যা বুদ্ধিমান নয় সেগুলি ব্যতিক্রম ধরছে ঠিক তাই আপনি স্ট্যাকের চিহ্নটি দূরে সরিয়ে ফেলতে পারেন বা আরও খারাপ, এটি খান।
Corlettk

10

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

ঠিক না, এটি এক নয়। এটি ব্যতিক্রমের স্ট্যাকট্রেস পুনরায় সেট করে। যদিও আমি একমত যে এটি সম্ভবত একটি ভুল, এবং এইভাবে খারাপ কোডের একটি উদাহরণ।


8

আপনি প্রাক্তন ছোঁড়াতে চান না - কারণ এটি কল স্ট্যাকটি হারাবে। দেখুন ব্যতিক্রম হ্যান্ডলিং (দুটিই MSDN)।

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


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

5

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

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

বেশিরভাগ নেট ভাষায় কোড ব্যতিক্রমের ভিত্তিতে ব্যবস্থা নেওয়ার একমাত্র উপায় হ'ল catchএটি (যদিও এটি জানেন যে এটি ব্যতিক্রমটি সমাধান করতে যাচ্ছে না), প্রশ্নে ক্রিয়াটি সম্পাদন করুন এবং তারপরে পুনরায় পুনরুদ্ধার করুন throw। কোডটি কী ব্যতিক্রম ছুঁড়েছে সে সম্পর্কে যত্নশীল না হলে অন্য একটি সম্ভাব্য উপায় হল একটি okব্লকযুক্ত পতাকা ব্যবহার করা try/finally; ব্লকটির আগে এবং ব্লকটি বেরিয়ে যাওয়ার আগে এবং ব্লকের মধ্যে থাকা কোনওর আগে okপতাকাটি সেট করুন । তারপরে, ধরে নিন যে সেট না করা থাকলে অবশ্যই একটি ব্যতিক্রম ঘটেছে। এই জাতীয় দৃষ্টিভঙ্গি শব্দার্থগতভাবে একটি / এর চেয়ে ভাল তবে এটি কুশ্রী এবং এটির তুলনায় এটি কম রক্ষণাবেক্ষণযোগ্য।falsetruereturnfinallyokcatchthrow


5

আপনার প্রোগ্রামিং কোনও লাইব্রেরি বা dll এর জন্য কাজ করলে এটি কার্যকর হতে পারে।

এই রিথ্রো কাঠামোটি কল স্ট্যাককে উদ্দেশ্যমূলকভাবে পুনরায় সেট করতে ব্যবহার করা যেতে পারে যাতে ফাংশনের অভ্যন্তরে কোনও পৃথক ফাংশন থেকে বাদ দেওয়া ব্যতিক্রমটি দেখার পরিবর্তে আপনি নিজেই ফাংশন থেকে ব্যতিক্রম পান।

আমি মনে করি এটি কেবলমাত্র ব্যবহৃত হয়েছে যাতে নিক্ষিপ্ত ব্যতিক্রমগুলি পরিষ্কার হয় এবং গ্রন্থাগারের "শিকড়গুলিতে" না যায়।


3

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


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

3
লোকেরা আশা করে যে যখন তারা "চেষ্টা করুন try ফু ();} অবশেষে {বার (); write" লেখেন তখন ফু এবং বারের মধ্যে কিছুই চলবে না। কিন্তু এটা সত্য না; যদি আপনার কলকারী একটি ব্যতিক্রম ফিল্টার যুক্ত করে এবং কোনও 'হ'ল' ক্যাচ 'এবং ফু () ছুড়ে না দেয় তবে আপনার কলার থেকে অন্য কিছু এলোমেলো কোড আপনার শেষ (বার) চলার আগে চলে যাবে। এটি খুব খারাপ যদি আপনি আক্রমণকারী বা উন্নত সুরক্ষা ভঙ্গ করেন, এই প্রত্যাশা করে যে শেষ পর্যন্ত তারা 'অবিলম্বে' স্বাভাবিক অবস্থায় ফিরে আসবে এবং অন্য কোনও কোড অস্থায়ী পরিবর্তন দেখতে পাবে না।
ব্রায়ান

3

এটি ক্যাচ ব্লকে আপনি কী করছেন তা নির্ভর করে এবং আপনি যদি ত্রুটিটি কলিং কোডটিতে পাস করতে চান তবে তা নির্ভর করে।

আপনি বলতে পারেন Catch io.FileNotFoundExeption exএবং তারপরে একটি বিকল্প ফাইল পাথ বা এই জাতীয় কিছু ব্যবহার করতে পারেন তবে তবুও ত্রুটিটি নিক্ষেপ করুন।

এছাড়াও করছেন Throwপরিবর্তে Throw Exআপনি সম্পূর্ণ স্ট্যাক ট্রেস রাখার অনুমতি দেয়। থ্রো প্রাক্তন স্ট্রোকের ট্রেসটিকে স্ট্রেস স্টেটমেন্ট থেকে পুনরায় সূচনা করে (আমি আশা করি এটি উপলব্ধি করে)।


3

অন্য উত্তরগুলির মধ্যে বেশিরভাগই আপনি কেন একটি ব্যতিক্রম পুনর্বিবেচন করতে চাইতে পারেন তার ভাল উদাহরণ প্রদান করে, তবে কেউ 'শেষ পর্যন্ত' দৃশ্যের উল্লেখ করেছে বলে মনে হয় না।

এর উদাহরণ যেখানে আপনার একটি পদ্ধতি রয়েছে যেখানে আপনি কার্সারটি সেট করেছেন (উদাহরণস্বরূপ অপেক্ষা কর্সারের ক্ষেত্রে), পদ্ধতিটিতে বেশ কয়েকটি প্রস্থান পয়েন্ট রয়েছে (যেমন (যদি)) ফিরে আসে এবং আপনি নিশ্চিত করতে চান যে কার্সারটি পুনরায় সেট করা হয়েছে পদ্ধতি শেষ।

এটি করার জন্য আপনি একটি কোড / ক্যাচ / অবশেষে সমস্ত কোড মোড়ানো করতে পারেন। শেষ পর্যন্ত কার্সারটি ডান কার্সারে ফিরে আসুন। যাতে আপনি কোনও বৈধ ব্যতিক্রমগুলি কবর না দেন, এটি ধরায় পুনরায় সেট করুন।

try
{
    Cursor.Current = Cursors.WaitCursor;
    // Test something
    if (testResult) return;
    // Do something else
}
catch
{
    throw;
}
finally
{
     Cursor.Current = Cursors.Default;
}

1
Historতিহাসিকভাবে catchএকটি বাধ্যতামূলক অংশ ছিল try...finally, বা এটি এই উদাহরণে কার্যকরী ভূমিকা পালন করে? - আমি কেবল ডাবল-চেক করেছি এবং আমি try {} finally {}ক্যাচ ব্লক ছাড়াই ব্যবহার করতে সক্ষম to
সেবি

2

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

তবে আপনি কিছু যুক্তি (উদাহরণস্বরূপ ফাইল লকের SQL সংযোগ বন্ধ করতে বা কিছু লগিং) করতে ব্যতিক্রমকে ধরতে পারেন, ব্যতিক্রম ঘটলে তা মোকাবেলার জন্য কলিং কোডটিতে ফিরিয়ে দেয়। এটি ফ্রন্ট এন্ড কোডের চেয়ে ব্যবসায়িক স্তরে বেশি সাধারণ হবে কারণ আপনি কোডার আপনার ব্যবসায়ের স্তরটি ব্যতিক্রমটি পরিচালনা করতে চান।

পুনরায় পুনরুক্তি করা যদিও আপনার পোস্ট করা উদাহরণটিতে ব্যতিক্রমটি ধরার কোনও পয়েন্ট নেই। এমনটা করবেন না!


1

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

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


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

5
ধরার, লগ ইন করার, পুনরায় পুনঃস্থাপনের প্রচুর কারণ রয়েছে। বিশেষত যদি ক্যাচ লগ সহ পদ্ধতিতে তথ্য থাকে তবে আপনি পদ্ধতিটি বাইরে চলে গেলে একবার হারাবেন। ত্রুটিটি পরে পরিচালিত হতে পারে তবে লগ করা হয়নি এবং আপনি সিস্টেমের ত্রুটিগুলি সম্পর্কে তথ্য হারিয়েছেন।
অ্যান্ডি

1
এই যেখানে ব্যতিক্রম শ্রেণীর ডেটা সম্পত্তি হ'ল জেনেরিক লগিংয়ের জন্য স্থানীয় সমস্ত তথ্য ক্যাপচার করে। এই নিবন্ধটি মূলত এটি আমার নজরে এনেছে: blog.abodit.com/2010/03/…
ম্যাকগুইয়ারভি 10

1

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


যদিও এই লিঙ্কটি প্রশ্নের উত্তর দিতে পারে, উত্তরের প্রয়োজনীয় অংশগুলি এখানে অন্তর্ভুক্ত করা এবং রেফারেন্সের জন্য লিঙ্কটি সরবরাহ করা ভাল। লিঙ্কযুক্ত পৃষ্ঠাগুলি পরিবর্তিত হলে লিঙ্ক-শুধুমাত্র উত্তরগুলি অবৈধ হতে পারে। - পর্যালোচনা থেকে
LHIOUI

@ হামজাএলএইচ, আমি সম্মত হই যে এটি কোনও লিখিত উত্তর নয়, তবে এর অন্যান্য তথ্য এবং ধনাত্মক ভোটের চেয়ে আলাদা তথ্য রয়েছে। সুতরাং আমি বুঝতে পারি না, কেন আপনি এটি মুছার পরামর্শ দিচ্ছেন? "সংক্ষিপ্ত উত্তরগুলি যা বিষয়বস্তুতে রয়েছে এবং সমাধান দেয় সেগুলি এখনও উত্তর।" মেটা.স্ট্যাকেক্সেঞ্জিং / প্রশ্ন
মাইকেল ফ্রেইজিম

এটি লিংক-কেবল উত্তর
LHIOUI

1. লিঙ্ক-কেবল উত্তরগুলি মুখ্য নয়, মন্তব্যে পরিবর্তন হওয়া উচিত। ২. এটি অন্যান্য এসও প্রশ্নের একটি উল্লেখ, বাহ্যিক সাইটের নয়, যা সময়ের সাথে সাথে ভেঙে যাওয়ার সম্ভাবনা কম বলে বিবেচিত। ৩. এর কিছু অতিরিক্ত বিবরণ রয়েছে, যা এটিকে "কেবলমাত্র লিঙ্ক" হিসাবে তৈরি করে না - দেখুন meta.stackexchange.com/questions/225370/…
মাইকেল ফ্রেইজিম

1

বেশিরভাগ উত্তর দৃশ্য-কাহিনী লগ-পুনর্বিবেচনা সম্পর্কে কথা বলছে।

আপনার কোডে এটি লেখার পরিবর্তে এওপি ব্যবহারের জন্য বিশেষত পোস্টশার্প.ডায়াগনস্টিক.অনএক্সসেপশনঅ্যাপশনস ইনক্লুডপ্যারামিটারভ্যালু এবং অন্তর্ভুক্তি এই অরগমেন্ট সহ টুলকিট বিবেচনা করুন


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

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

স্ট্যাকওভারফ্লোতে কেবল এই পরামর্শ রয়েছে।
টনি ডং 21

@ টনিডং, যদি উত্তরটি একেবারে অকেজো না হয় তবে আপনার উচিত "ঠিক আছে" দেখাচ্ছে
মাইকেল ফ্রেইজিম

0

throwযখন আপনার কাছে বর্তমান ব্যতিক্রমগুলি পরিচালনা করার জন্য কোনও নির্দিষ্ট কোড না থাকে বা যখন নির্দিষ্ট ত্রুটির ক্ষেত্রে আপনার যদি যুক্তি থাকে তবে অন্য সমস্ত কিছু এড়িয়ে যেতে চান সেগুলি দিয়ে ব্যাতিক্রমগুলি ব্যতিক্রমগুলি কার্যকর হয়।

উদাহরণ:

string numberText = "";
try
{
    Console.Write("Enter an integer: ");
    numberText = Console.ReadLine();
    var result = int.Parse(numberText);

    Console.WriteLine("You entered {0}", result);
}
catch (FormatException)
{
    if (numberText.ToLowerInvariant() == "nothing")
    {
        Console.WriteLine("Please, please don't be lazy and enter a valid number next time.");
    }
    else
    {
        throw;
    }
}    
finally
{
    Console.WriteLine("Freed some resources.");
}
Console.ReadKey();

তবে ক্যাপ ব্লকগুলিতে শর্তাধীন ক্লজগুলি ব্যবহার করে এটি করার আরও একটি উপায় রয়েছে :

string numberText = "";
try
{
    Console.Write("Enter an integer: ");
    numberText = Console.ReadLine();
    var result = int.Parse(numberText);

    Console.WriteLine("You entered {0}", result);
}
catch (FormatException) when (numberText.ToLowerInvariant() == "nothing")
{
    Console.WriteLine("Please, please don't be lazy and enter a valid number next time.");
}    
finally
{
    Console.WriteLine("Freed some resources.");
}
Console.ReadKey();

.NET রানটাইমটি পুনরায় নিক্ষেপের আগে ব্যতিক্রম বস্তুটিকে পুনর্নির্মাণ করতে হবে না বলে এই ব্যতিক্রমটি পুনরায় নিক্ষেপের চেয়ে আরও কার্যকর।

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