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.

···

--
Posted via http://www.ruby-forum.com/.

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 }

--
Posted via http://www.ruby-forum.com/\.

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

···

--
Posted via http://www.ruby-forum.com/.

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

···

___________________________________
SpecialException = "Special exception"
begin

  begin
    raise SpecialException
  rescue SpecialException
    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?

--
Posted via http://www.ruby-forum.com/.

Thanks for the great answer, what is second rescue?

···

--
Posted via http://www.ruby-forum.com/.

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?

···

--
Posted via http://www.ruby-forum.com/\.

Joel Pearson 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.

···

--
Posted via http://www.ruby-forum.com/\.

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

···

On Tue, Oct 23, 2012 at 8:10 AM, ajay paswan <lists@ruby-forum.com> wrote:

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?

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

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

···

--
Posted via http://www.ruby-forum.com/\.

Brian Candler wrote in post #1080999:

Joel Pearson 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.

···

--
Posted via http://www.ruby-forum.com/\.