How does SystemExit
behave differently from other Exception
s? 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?)
The docs say that calling sys. exit() raises a SystemExit exception which can be caught in outer levels.
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”.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With