How to rescue any exception in 1.8?

Discussion in 'Ruby' started by Philip Mak, Jul 26, 2003.

  1. Philip Mak

    Philip Mak Guest

    This code will catch the exception in Ruby 1.6:

    require 'timeout'
    begin
    raise TimeoutError
    rescue
    puts "Rescued!"
    end

    But in Ruby 1.8, it will not catch the exception. I found out that if
    I do "rescue Exception" instead of just "rescue", it will work.

    So, my question is, if I want to rescue any exception no matter what
    it is, do I have to start typing "rescue Exception" instead of
    "rescue"?
     
    Philip Mak, Jul 26, 2003
    #1
    1. Advertising

  2. Philip Mak

    Kent Dahl Guest

    Philip Mak wrote:
    >
    > This code will catch the exception in Ruby 1.6:
    >
    > require 'timeout'
    > begin
    > raise TimeoutError
    > rescue
    > puts "Rescued!"
    > end
    >
    > But in Ruby 1.8, it will not catch the exception. I found out that if
    > I do "rescue Exception" instead of just "rescue", it will work.
    >
    > So, my question is, if I want to rescue any exception no matter what
    > it is, do I have to start typing "rescue Exception" instead of
    > "rescue"?


    Yes.

    Rescue without an Exception type only catches StandardError and
    subclasses. The inheritance hierarchy of exceptions are one of the
    changes between 1.6 and 1.8, IIRC...

    [kentda@v052a kentda]$ ruby -v -e "require 'timeout';p
    TimeoutError.ancestors"
    ruby 1.6.8 (2002-12-24) [i386-linux-gnu]
    [TimeoutError, StandardError, Exception, Object, Kernel]

    [kentda@v052a kentda]$ /usr/local/bin/ruby -v -e "require 'timeout';p
    TimeoutError.ancestors"
    ruby 1.8.0 (2003-07-24) [i686-linux]
    [Timeout::Error, Interrupt, SignalException, Exception, Object, Kernel]

    HTH

    --
    (\[ Kent Dahl ]/)_ _~_ _____[ http://www.pvv.org/~kentda/ ]_____/~
    ))\_student_/(( \__d L b__/ (pre-) Master of Science in Technology )
    ( \__\_õ|õ_/__/ ) _)Industrial economics and technological management(
    \____/_ö_\____/ (____engineering.discipline_=_Computer::Technology___)
     
    Kent Dahl, Jul 26, 2003
    #2
    1. Advertising

  3. On Sun, Jul 27, 2003 at 05:50:32AM +0900, Philip Mak wrote:
    > This code will catch the exception in Ruby 1.6:
    >
    > require 'timeout'
    > begin
    > raise TimeoutError
    > rescue
    > puts "Rescued!"
    > end
    >
    > But in Ruby 1.8, it will not catch the exception. I found out that if
    > I do "rescue Exception" instead of just "rescue", it will work.
    >
    > So, my question is, if I want to rescue any exception no matter what
    > it is, do I have to start typing "rescue Exception" instead of
    > "rescue"?


    In general, you always did:

    $ ruby16 -ve 'begin; require "flurble"; rescue; puts "ok"; end'
    ruby 1.6.8 (2002-12-24) [i386-freebsd4.8]
    -e:1:in `require': No such file to load -- flurble (LoadError)
    from -e:1

    $ ruby16 -ve 'begin; require "flurble"; rescue Exception; puts "ok"; end'
    ruby 1.6.8 (2002-12-24) [i386-freebsd4.8]
    ok

    'rescue' by itself is like 'rescue StandardError', I believe (which catches
    StandardError and all its subclasses)

    However it does look like timeout exceptions have changed from 1.6.8 to 1.8

    1.6.8: raised TimeoutError, which was a subclass of StandardError
    1.8.0: raises Timeout::Error, which is a subclass of Interrupt

    However in 1.8.0 you can pass in an exception class, so you can do:

    require 'timeout'
    begin
    timeout(3, StandardError) do
    sleep 5
    end
    rescue
    puts "ok"
    end

    Or, to make your code compatible with both versions, without trapping
    absolutely every exception, you can do

    rescue StandardError, Interrupt

    Cheers,

    Brian.
     
    Brian Candler, Jul 26, 2003
    #3
  4. Unfortunately the on-line version of the Pickaxe book doesn't have the image
    which shows the exception hierarchy. There are probably a zillion programs
    for dumping this out, but here's another one anyway:

    require 'timeout'

    class ObjTree
    def initialize
    @children = Hash.new([])
    ObjectSpace.each_object(Class) do |c|
    @children[c.superclass] += [c]
    end
    end

    def dumptree(klass, level = 0)
    puts " "*level + "" + klass.to_s
    @children[klass].sort {|x,y| x.to_s<=>y.to_s}.each do |c|
    dumptree(c, level+1)
    end
    end
    end

    ObjTree.new.dumptree(Exception) # or try Object
     
    Brian Candler, Jul 26, 2003
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Xiangrong Fang

    rescue exception

    Xiangrong Fang, Aug 16, 2003, in forum: Ruby
    Replies:
    1
    Views:
    93
    Xiangrong Fang
    Aug 16, 2003
  2. Wes Gamble
    Replies:
    1
    Views:
    109
    Robert Klemme
    Nov 20, 2006
  3. Richard
    Replies:
    2
    Views:
    107
    Richard
    Dec 17, 2006
  4. Seth
    Replies:
    1
    Views:
    107
    Eric Hodel
    Jun 22, 2007
  5. Iñaki Baz Castillo
    Replies:
    14
    Views:
    182
    Robert Dober
    Jul 21, 2008
Loading...

Share This Page