SystemExit是一种特殊的异常吗?

时间:2011-02-25 15:02:33

标签: ruby exception-handling exit

SystemExit与其他Exception的行为有何不同?我想我理解为什么它不会很好地提出一个正确的异常的一些推理。例如,您不希望发生类似这样的奇怪事件:

begin
  exit
rescue => e
  # Silently swallow up the exception and don't exit
end

如何rescue忽略SystemExit? (它使用什么标准?)

2 个答案:

答案 0 :(得分:21)

当您在没有一个或多个班级的情况下编写rescue时,it is the same写作:

begin
  ...
rescue StandardError => e
  ...
end

但是,有些异常不会从StandardError继承。 SystemExit是其中之一,因此未被捕获。以下是Ruby 1.9.2中层次结构的一个子集,您可以find out yourself

BasicObject
  Exception
    NoMemoryError
    ScriptError
      LoadError
        Gem::LoadError
      NotImplementedError
      SyntaxError
    SecurityError
    SignalException
      Interrupt
    StandardError
      ArgumentError
      EncodingError
        Encoding::CompatibilityError
        Encoding::ConverterNotFoundError
        Encoding::InvalidByteSequenceError
        Encoding::UndefinedConversionError
      FiberError
      IOError
        EOFError
      IndexError
        KeyError
        StopIteration
      LocalJumpError
      NameError
        NoMethodError
      RangeError
        FloatDomainError
      RegexpError
      RuntimeError
      SystemCallError
      ThreadError
      TypeError
      ZeroDivisionError
    SystemExit
    SystemStackError
    fatal

您可以通过以下方式捕获 SystemExit

begin
  ...
rescue SystemExit => e
  ...
end

...或者您可以选择捕获每个例外,包括SystemExit

begin
  ...
rescue Exception => e
  ...
end

亲自尝试:

begin
  exit 42
  puts "No no no!"
rescue Exception => e
  puts "Nice try, buddy."
end
puts "And on we run..."

#=> "Nice try, buddy."
#=> "And on we run..."

请注意,此示例不适用于(某些版本的?)IRB,它提供了自己的退出方法,可以屏蔽正常的Object#exit。

在1.8.7中:

method :exit
#=> #<Method: Object(IRB::ExtendCommandBundle)#exit>

在1.9.3中:

method :exit
#=> #<Method: main.irb_exit>

答案 1 :(得分:0)

简单示例:

begin
  exit
  puts "never get here"
rescue SystemExit
  puts "rescued a SystemExit exception"
end

puts "after begin block"

退出status / success?等也可以阅读:

begin
  exit 1
rescue SystemExit => e
  puts "Success? #{e.success?}" # Success? false
end

begin
  exit
rescue SystemExit => e
  puts "Success? #{e.success?}" # Success? true
end

方法的完整列表:[:status, :success?, :exception, :message, :backtrace, :backtrace_locations, :set_backtrace, :cause]