小编典典

为什么在 Ruby 中 `rescue Exception => e` 是不好的风格?

all

Ryan Davis 的Ruby
QuickRef
说(没有解释):

不要抢救异常。曾经。否则我会刺伤你。

为什么不?什么是正确的做法?


阅读 174

收藏
2022-02-28

共1个答案

小编典典

TL;DR
StandardError改为用于一般异常捕获。当原始异常被重新引发时(例如,当救援只记录异常时),救援Exception可能是可以的。


ExceptionRuby
异常层次结构
的根,所以当你从 所有东西rescue Exception中拯救出来时,包括诸如、和. __SyntaxError``LoadError``Interrupt

救援Interrupt阻止用户使用CTRL``C退出程序。

救援SignalException会阻止程序正确响应信号。它将无法杀死,除非kill -9.

救援SyntaxError意味着eval失败的 s 会默默地这样做。

所有这些都可以通过运行这个程序来显示,并尝试CTRL``Ckill它:

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
2022-02-28