Rubyで例外をキャッチした後、(同じ例外を)消去します


86

例外をキャッチしてRubyスキルを向上させようとしています。複数のメソッド呼び出しがある場合に、同じ種類の例外を再発生させるのが一般的かどうかを知りたいです。それで、次のコードは意味がありますか?同じ種類の例外を再発生させても大丈夫ですか、それともプロセスメソッドでそれをキャッチするべきではありませんか?

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...:)が、プロセス自体によって起動された例外をキャッチしません、しかし、プロセス内から呼び出されたものの。それは正しいですか?
Hommer Smith

2
これによりstacktrace、元の例外がcause
失わ

4
@bjhaidraiseこの回答の方法で呼び出すと、を含め、元の例外が完全に保持されbacktraceます。causeこの場合には適用されません。むしろ、rescueブロックが新しい例外を発生させたときに自動的に入力されます。
担当者2017年

@HommerSmith:レイズ前の行(この場合はlog.errorですが、何でもかまいません)が失敗した場合はどうなりますか?私はそれを「保証する」ことを考えていますが、保証の内部では、エラーへの参照を「発生」の引数として使用する必要があります。あれについてどう思う?
jgomo3

1
@RafałCieślakエラーが発生するたびに、$!グローバル変数に割り当てられます。raise引数なしで呼び出すと$!、に含まれるエラーが発生し、最後のエラーが効果的に発生します。ただし、ローカル変数にraise error含まれるエラーが発生します。errorローカル変数は、に含まれるオブジェクトと同じである場合とそうでない場合があります$!。私の例で$!は、はと同じerrorです。しかし、それはこれを実行することも可能です:error = Exception.new; raise error
マテウス・モレイラ

4

これにより、元のエラーと同じタイプのエラーが発生しますが、メッセージをカスタマイズできます。

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

StandardErrorにはあらゆる種類の低レベルの関数が含まれており、プログラムがハングする可能性があるため、StandardErrorをキャッチすることはお勧めできません。
ポールホワイトヘッド

3
すぐに例外を再度発生させるため、これはルールの「例外」であると思います。
FreePender

@FreePender;)
ilasno20年

1
1年が経過したことは知っていますが、StandardError、@ PaulWhiteheadをキャッチするのは安全です。これは、絶対にキャッチしてはならない例外です。(クイック源:thoughtbot.com/blog/rescue-standarderror-not-exception
RonLugge
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.