Exception handelling in ruby

What is diffrence between:

rescue => e

and

rescue Exception => e

Is the error caught by 2nd one is included in the error caught by 1st?

How to know the type of error I am getting, because i have read that by
rescue we can catch particular kind of error.

For example: rescue ZeroDivisionError
catches an error by division by zero, how to know -the type of error
which is ‘ZeroDivisionError’ here.

ajay paswan wrote in post #1080695:

What is diffrence between:

rescue => e

and

rescue Exception => e

The first is equivalent to

rescue StandardError => e

Exception is the top level class. You usually don’t want to catch this;
it includes things like Interrupt (ctrl-C), NoMemoryError, SyntaxError
etc. which really ought to be fatal.

For example: rescue ZeroDivisionError
catches an error by division by zero, how to know -the type of error
which is ‘ZeroDivisionError’ here.

1/0
ZeroDivisionError: divided by 0
from (irb):7:in `/’
from (irb):7

ObjectSpace.each_object(Class).select { |e| e.ancestors.include? Exception }

Thanks for the great answer, what is second rescue?

something like the below would catch errors 1 and 2 respectively, and if
the error didn’t fall into those categories then the third rescue would
catch it.

rescue 1
rescue 2
rescue

but I have seen that in the following two statements

rescue => e
and
rescue Exception => e

The ‘execution expired’ error is caught by second statement, but not
first statement… WHY?

rescue => e
This rescues any error and lets you use ‘e’ as a variable to inspect the
error.

rescue StandardError => e
This rescues any error which falls into the ‘StandardError’ group, and
lets you use ‘e’ as a variable to inspect the error.

Think of rescue as a case statement or ‘if’ operator. You can rescue
specific errors using multiple rescue lines.

something like the below would catch errors 1 and 2 respectively, and if
the error didn’t fall into those categories then the third rescue would
catch it.

rescue 1
rescue 2
rescue

On Tue, Oct 23, 2012 at 8:10 AM, ajay paswan [email protected]
wrote:

rescue => e
and
rescue Exception => e

The ‘execution expired’ error is caught by second statement, but not
first statement… WHY?

We cannot know the type of exception if you do not post it. One
possible explanation:

irb(main):031:0> begin
irb(main):032:1* raise ‘execution expired’
irb(main):033:1> rescue => e
irb(main):034:1> printf “empty: %p\n”, e
irb(main):035:1> rescue Exceptin => e
irb(main):036:1> printf “Exception: %p\n”, e
irb(main):037:1> end
empty: #<RuntimeError: execution expired>
=> nil
irb(main):038:0> p RuntimeError.ancestors
[RuntimeError, StandardError, Exception, Object, PP::ObjectMixin,
Kernel, BasicObject]
=> [RuntimeError, StandardError, Exception, Object, PP::ObjectMixin,
Kernel, BasicObject]
irb(main):039:0>

Note that a rescue clause causes all exceptions of the declared class
and subclasses. Also handlers are processed from top to bottom and
the first matching handler is used.

Kind regards

robert

Maybe another possible explanation would be nested blocks? We haven’t
seen the layout of the code you’re using, but consider this:


SpecialException = Exception.new “Special exception”
begin

begin
raise SpecialException
rescue SpecialException => e
puts e.message
puts e.backtrace.inspect
raise “Found an error!”
rescue Exception => e
puts e.message
puts e.backtrace.inspect
raise “Found an error!”
end

rescue #This is going to trap the previous raise statements

puts “rescued error: #{$!}”

end


That rescue on the outside will catch anything raised within the
previous error handler. Maybe the layout of your code is causing your
problem?

ajay paswan wrote in post #1080767:

but I have seen that in the following two statements

rescue => e
and
rescue Exception => e

The ‘execution expired’ error is caught by second statement, but not
first statement… WHY?

Because the first is

rescue StandardError => e

and only catches those exceptions which are under StandardError.

“execution expired” is probably Timeout::Error from timeout.rb. This is
a subclass of Interrupt, which is not underneath StandardError.

So to rescue it:

require ‘timeout’
begin
Timeout::timeout(5) { sleep(10) }
rescue Timeout::Error
puts “I had enough”
end

I strongly recommend you rescue exactly the exception you want, and not
“Exception”.

Brian C. wrote in post #1080999:

Joel P. wrote in post #1080729:

rescue => e
This rescues any error and lets you use ‘e’ as a variable to inspect the
error.

That is incorrect.

rescue => e

only rescues exceptions which are StandardError and its descendants.
That is, it is exactly the same as

rescue StandardError => e

something like the below would catch errors 1 and 2 respectively, and if
the error didn’t fall into those categories then the third rescue would
catch it.

rescue 1
rescue 2
rescue

No, a bare “rescue” also only captures StandardError and its children.

If you want to rescue absolutely every exception then you need to
write explicitly:

rescue Exception

However, as I said before, this is almost always a bad idea, because
exceptions outside of StandardError are things you rarely want to catch;
things that mean your interpreter has blown up in such a bad way that
it’s pointless attempting to continue, and catching it will only prolong
the pain.

D’oh! I forgot that Exception covers more than the default rescue.
Brian is right, try to avoid rescuing something as all-encompassing as
“Exception”. If you want to know what your error is, you can do a test
run which causes the failure, and try something like “e.class” to
ascertain the type of error you need to handle.

Joel P. wrote in post #1080729:

rescue => e
This rescues any error and lets you use ‘e’ as a variable to inspect the
error.

That is incorrect.

rescue => e

only rescues exceptions which are StandardError and its descendants.
That is, it is exactly the same as

rescue StandardError => e

something like the below would catch errors 1 and 2 respectively, and if
the error didn’t fall into those categories then the third rescue would
catch it.

rescue 1
rescue 2
rescue

No, a bare “rescue” also only captures StandardError and its children.

If you want to rescue absolutely every exception then you need to
write explicitly:

rescue Exception

However, as I said before, this is almost always a bad idea, because
exceptions outside of StandardError are things you rarely want to catch;
things that mean your interpreter has blown up in such a bad way that
it’s pointless attempting to continue, and catching it will only prolong
the pain.