Roger said:
which always surprises me. Any preferences over always rescuing
Exception?
It looks pretty consistent to me. The default is to catch StandardError,
and most "normal" errors are subclasses of this. Only gross system-level
errors are outside of this, and you probably didn't want to catch them
anyway.
There was talk of ruby-1.9 moving NoMethodError outside of StandardError
- or at least, (x rescue y) not catching it - but a test suggests that
hasn't been done.
Anyway, here's a program you can use to demonstrate how consistent it
is. If you can show something inconsistent, please update the code to
show it.
require 'timeout'
RAISERS = [
["timeout error", lambda { raise Timeout::Error }],
["bad method name", lambda { zxkjcnvkj }],
["divide by zero", lambda { 1/0 }],
["Exception", lambda { raise Exception }],
]
CATCHERS = [
["rescue blank", lambda { |r|
begin
r.call
rescue
end
}],
["rescue => e", lambda { |r|
begin
r.call
rescue => e
end
}],
["rescue StandardError", lambda { |r|
begin
r.call
rescue StandardError
end
}],
["expr rescue expr", lambda { |r|
r.call rescue nil
}],
["rescue Exception", lambda { |r|
begin
r.call
rescue Exception
end
}],
]
CATCHERS.each do |c|
puts "*** For #{c.first}"
RAISERS.each do |r|
begin
c[1].call(r[1])
rescue Exception
puts " Didn't catch #{r[0]}"
else
puts " Caught #{r[0]}"
end
end
end
$ ruby raiser.rb
*** For rescue blank
Caught timeout error
Caught bad method name
Caught divide by zero
Didn't catch Exception
*** For rescue => e
Caught timeout error
Caught bad method name
Caught divide by zero
Didn't catch Exception
*** For rescue StandardError
Caught timeout error
Caught bad method name
Caught divide by zero
Didn't catch Exception
*** For expr rescue expr
Caught timeout error
Caught bad method name
Caught divide by zero
Didn't catch Exception
*** For rescue Exception
Caught timeout error
Caught bad method name
Caught divide by zero
Caught Exception