Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is SystemExit a special kind of Exception?

How does SystemExit behave differently from other Exceptions? I think I understand some of the reasoning about why it wouldn't be good to raise a proper Exception. For example, you wouldn't want something strange like this to happen:

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

But how does the rescue ignore SystemExit? (What criteria does it use?)

like image 994
Benjamin Oakes Avatar asked Feb 25 '11 15:02

Benjamin Oakes


People also ask

Does SYS exit throw exception?

The docs say that calling sys. exit() raises a SystemExit exception which can be caught in outer levels.

What is System exit in Python?

exit() function allows the developer to exit from Python. The exit function takes an optional argument, typically an integer, that gives an exit status. Zero is considered a “successful termination”.


1 Answers

When you write rescue without one or more classes, it is the same as writing:

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

There are Exceptions that do not inherit from StandardError, however. SystemExit is one of these, and so it is not captured. Here is a subset of the hierarchy in Ruby 1.9.2, which you can 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

You can thus capture just SystemExit with:

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

...or you can choose to capture every exception, including SystemExit with:

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

Try it yourself:

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..."

Note that this example will not work in (some versions of?) IRB, which supplies its own exit method that masks the normal Object#exit.

In 1.8.7:

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

In 1.9.3:

method :exit
#=> #<Method: main.irb_exit>
like image 180
Phrogz Avatar answered Nov 15 '22 11:11

Phrogz