1. ホーム
  2. ruby

[解決済み] Rubyで「例外 => e」を救済するのはなぜ悪いスタイルなのですか?

2022-03-19 14:35:19

質問

ライアン・デイビスの Ruby QuickRef と書いてあります(説明なし)。

エクセプションの救出はしないでください。EVER.でないと刺すぞ。

なぜダメなのか?何が正解なんだ?

どうすればいい?

TL;DR : 使用方法 StandardError の代わりに、一般的な例外をキャッチするために使用します。元の例外が再び発生した場合 (例: 例外をログに残すためだけのレスキューの場合)、レスキューの際に Exception は大丈夫でしょう。


Exception のルートです。 Rubyの例外階層 というように rescue Exception から救出します。 すべて のようなサブクラスも含まれます。 SyntaxError , LoadError および Interrupt .

レスキュー Interrupt を使用することを防ぎます。 CTRL C をクリックしてプログラムを終了します。

レスキュー SignalException は、プログラムがシグナルに正しく反応しないようにします。によってのみ殺すことができるようになります。 kill -9 .

レスキュー SyntaxError というのは eval が失敗した場合、それは無言で行われます。

これらはすべて、このプログラムを実行し、次のように試してみることで示すことができます。 CTRL C または kill を使用します。

loop do
  begin
    sleep 1
    eval "djsakru3924r9eiuorwju3498 += 5u84fior8u8t4ruyf8ihiure"
  rescue Exception
    puts "I refuse to fail or be stopped!"
  end
end

から救出する。 Exception はデフォルトでもありません。すること

begin
  # iceberg!
rescue
  # lifeboats
end

から救出することはできません。 Exception から救出し StandardError . 一般的には、デフォルトの StandardError からの救出は Exception 広げる は、範囲を狭めるどころか、壊滅的な結果をもたらし、バグ探しを極めて困難なものにします。


からのレスキューを行いたい場合。 StandardError で、例外を持つ変数が必要な場合、このフォームを使用することができます。

begin
  # iceberg!
rescue => e
  # lifeboats
end

と等価である。

begin
  # iceberg!
rescue StandardError => e
  # lifeboats
end


から救出するのがまともな数少ない一般的なケースの一つです。 Exception はロギングやレポートのためで、その場合はすぐに例外を再レイズする必要があります。

begin
  # iceberg?
rescue Exception => e
  # do some logging
  raise # not enough lifeboats ;)
end