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
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.
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.
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?
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.
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.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.