রুবীতে একটি ব্যতিক্রম ধরা পরে পুনরায় (একই ব্যতিক্রম)


86

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

class Logo
  def process
    begin
      @processed_logo = LogoProcessor::create_image(self.src)
    rescue CustomException
      raise CustomException
    end
  end
end

module LogoProcessor
  def self.create_image
    raise CustomException if some_condition
  end
end

উত্তর:


175

কখনও কখনও আমরা কেবল ত্রুটিটি আসলে ত্রুটিটি পরিচালনা না করেই ঘটেছিল তা জানতে চাই ।

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

উদাহরণস্বরূপ, যদি আমরা ত্রুটি বার্তাটি লগ করতে এবং তারপরে কলকারীকে এটির সাথে যোগাযোগ করতে পারি তবে কী হবে?

begin
  this_will_fail!
rescue Failure => error
  log.error error.message
  raise
end

raiseকোনও যুক্তি ছাড়াই কল করা শেষ ত্রুটি বাড়িয়ে তুলবে। আমাদের ক্ষেত্রে, আমরা আবার উত্থাপন করছি error

আপনি আপনার প্রশ্নে যে উদাহরণটি উপস্থাপন করেছেন, ত্রুটিটিকে পুনরায় উত্থাপন করা সহজভাবে প্রয়োজনীয় নয়। আপনি কেবল এটিকে প্রাকৃতিকভাবে স্ট্যাকটি প্রচার করতে দিতে পারেন। আপনার উদাহরণের মধ্যে পার্থক্য হ'ল আপনি একটি নতুন ত্রুটিযুক্ত বস্তু তৈরি করছেন এবং শেষটিকে পুনরায় উত্থাপনের পরিবর্তে এটি উত্থাপন করুন।


মজাদার. আমার প্রশ্নটি হ'ল আমি যদি প্রক্রিয়া সংজ্ঞায় ত্রুটিটি না ধরি, তবে আমি যখন প্রক্রিয়া পদ্ধতিটি কল করি তখন এটি ধরতে হবে, উদাহরণস্বরূপ: begin @logo.process; rescue...তবে তারপরে আমি প্রক্রিয়া নিজেই চালু হওয়া ব্যতিক্রম ধরা পড়ব না, কিন্তু প্রক্রিয়া মধ্যে থেকে বলা হয়েছে যে কিছু। এটা কি সঠিক?
হোমার স্মিথ

4
এটি stacktraceআসল ব্যতিক্রম থেকে মুক্ত হয়ে যাবে , আপনি সম্ভবত ব্যতিক্রমটি অন্তর্ভুক্ত করতে চান causeযা রুবি> ২.১ এ পাওয়া যায়
বিজেদ

4
@bjhaid কলিং raiseএই উত্তরটি এর পদ্ধতিতে সম্পূর্ণভাবে মূল ব্যতিক্রম অপরিবর্তিত সহ backtracecauseএই ক্ষেত্রে প্রযোজ্য না। বরং কোনও rescueব্লক নতুন ব্যতিক্রম উত্থাপন করলে তা স্বয়ংক্রিয়ভাবে পপুলেটে যায়।
প্রতিনিধির

@ হোমারস্মিথ: যদি লাইনটি উত্থাপনের আগে (এই ক্ষেত্রে log.error তবে এটি কিছু হতে পারে) ব্যর্থ হয় তবে কী হবে? আমি এটি "নিশ্চিতকরণ" করার বিষয়ে চিন্তাভাবনা করছি, তবে, এই নিশ্চয়তার অভ্যন্তরে আমাকে "উত্থাপন" এর যুক্তি হিসাবে ত্রুটির রেফারেন্সটি ব্যবহার করতে হবে। তুমি এটা সম্পর্কে কী ভাব?
jgomo3

4
@ রাফাłসিএলাক প্রতিবার কোনও ত্রুটি উত্থাপিত হলে, এটি $!বিশ্বব্যাপী পরিবর্তনশীলকে বরাদ্দ করা হয় । raiseযুক্তি ছাড়াই কল করা অন্তর্ভুক্ত থাকা ত্রুটিটিকে $!কার্যকরভাবে শেষ ত্রুটিটি উত্থাপন করে। তবে, স্থানীয় ভেরিয়েবলের raise errorমধ্যে থাকা ত্রুটি বাড়িয়ে তুলবে error, যা এতে অন্তর্ভুক্ত একই জিনিস হতে পারে বা নাও হতে পারে $!। আমার উদাহরণে, $!হিসাবে একই error। যাইহোক, এটি করাও সম্ভব:error = Exception.new; raise error
ম্যাথিউস মোরেইরা

4

এটি মূল হিসাবে একই ধরণের ত্রুটি বাড়িয়ে তুলবে, তবে আপনি বার্তাটি কাস্টমাইজ করতে পারেন।

rescue StandardError => e
  raise e.class, "Message: #{e.message}"

আমি স্ট্যান্ডার্ডেরার ধরার পক্ষে এটির একটি খারাপ ধারণা প্রস্তাব করব কারণ এতে সমস্ত ধরণের নিম্ন স্তরের ফাংশন রয়েছে এবং এটি আপনার প্রোগ্রামটি স্তব্ধ করতে পারে।
পল হোয়াইটহেড

4
আমি বিশ্বাস করি এটি নিয়মের একটি "ব্যতিক্রম", যেহেতু আমরা তাত্ক্ষণিকভাবে আবার ব্যতিক্রম উত্থাপন করছি।
ফ্রিপেন্ডার

আমি সেখানে আপনি কী করেছেন তা দেখুন, @ ফ্রিপেন্ডার;)
ইলাসনো

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