Ruby で `rescue Exception => e` を使用するのはなぜ悪いスタイルなのでしょうか? 質問する

Ruby で `rescue Exception => e` を使用するのはなぜ悪いスタイルなのでしょうか? 質問する

ライアン・デイビスのRuby クイックリファレンス(説明なしで)こう言う:

Exception を救出しないでください。絶対に。さもないと、刺し殺します。

なぜダメなの? 何をするのが正しいの?

ベストアンサー1

TL;DR :StandardError一般的な例外キャッチには代わりに使用します。元の例外が再度発生した場合 (例外のみをログに記録するためにレスキューする場合など)、レスキューはExceptionおそらく問題ありません。


Exceptionの根源はRubyの例外階層なので、 を使用すると、 、、 などのサブクラスを含むすべてrescue Exceptionの から rescue できます。SyntaxErrorLoadErrorInterrupt

レスキューによりInterrupt、ユーザーはCTRLCプログラムを終了できなくなります。

RescueSignalExceptionにより、プログラムがシグナルに正しく応答できなくなります。 以外では強制終了できませんkill -9

救助とは、失敗した が静かに救助されるSyntaxErrorことを意味します。eval

これらはすべて、このプログラムを実行し、または実行することによって表示できCTRLCます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

レスキューを実行するのが理にかなっている数少ない一般的なケースの 1 つは、Exceptionログ記録やレポート作成の目的です。この場合は、例外をすぐに再度発生させる必要があります。

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

おすすめ記事