【问题标题】:Is SystemExit a special kind of Exception?SystemExit 是一种特殊的异常吗?
【发布时间】:2011-07-04 09:00:07
【问题描述】:

SystemExit 与其他Exception 的行为有何不同?我想我理解了为什么提出适当的异常不会好的原因。例如,您不希望发生这种奇怪的事情:

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

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

【问题讨论】:

  • @AndrewGrimm 这当然是来自邮件列表和 IRC 的常见问题解答,但我似乎无法在 S/O 上完全找到这个问题。我找到的最接近的是 "Which exceptions do you catch when you don't specify an exception class in Ruby",但这是一个重复的答案,而不是重复的问题。
  • @Andrew 我认为其他人也必须问同样的问题,但我没有找到任何具体回答如何处理SystemExit 的内容。 @Phrogz 感谢您提供相关问题的链接。

标签: ruby exception-handling exit


【解决方案1】:

简单示例:

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]

【讨论】:

    【解决方案2】:

    当你写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>
    

    【讨论】:

    • 感谢您的信息。我知道你可以自己捕获SystemExit,但我不知道不指定异常类只会导致StandardError 异常被抢救。似乎可以解释它 - 谢谢!
    • 这对于测试是否存在某些东西非常棒
    猜你喜欢
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 2014-12-24
    相关资源
    最近更新 更多