Programmatically and dynamically catching exceptions

Discussion in 'Ruby' started by Logan Capaldo, Nov 3, 2004.

  1. Allright here was my idea which seems to have been shattered by the
    realities of Ruby.

    I was thinking of a class called Try. You would do something like

    class Try
    ...
    end

    tryblock = Try.new { #This block would normally be wrapped in a begin...rescue
    }

    tryblock.add_exhandler:)SomeException) { |ex| some_code }

    tryblock.execute #or possibly tryblock.call ?

    Basically the idea was going to be you could subclass Try and provide
    default sensible handling of your Exceptions (if you were writing a
    library for instance) . Users could then then wrap it in a
    begin...rescue block to catch other exceptions or use add_exhandler to
    overide the default handler. (Possibly provide a way to get the old
    handler and and use it in the new).

    my idea was going to be that I could do something like

    begin
    user_proc.call
    [SomeEx1, SomeEx2, etc..].each do |ex|
    rescue ex => e
    handler_hash[ex].call(e)
    end

    Unfortunately the syntax doesn;t seem to allow for this. Am I missing
    something? is this just a really bad idea?
    Logan Capaldo, Nov 3, 2004
    #1
    1. Advertising

  2. Logan Capaldo <> writes:

    > Allright here was my idea which seems to have been shattered by the
    > realities of Ruby.
    >
    > I was thinking of a class called Try. You would do something like
    >
    > class Try
    > ...
    > end
    >
    > tryblock = Try.new { #This block would normally be wrapped in a begin...rescue
    > }
    >
    > tryblock.add_exhandler:)SomeException) { |ex| some_code }
    >
    > tryblock.execute #or possibly tryblock.call ?
    >
    > Basically the idea was going to be you could subclass Try and provide
    > default sensible handling of your Exceptions (if you were writing a
    > library for instance) . Users could then then wrap it in a
    > begin...rescue block to catch other exceptions or use add_exhandler to
    > overide the default handler. (Possibly provide a way to get the old
    > handler and and use it in the new).
    >
    > my idea was going to be that I could do something like
    >


    class Try
    def execute
    begin
    user_proc.call(*user_proc_args)
    rescue Error => e
    elt = (exhandlers.select{|obj| e.class == obj.exception_class})[0]
    if elt
    elt.exception_handler.call(e)
    else
    raise e
    end
    end
    end
    end


    YS.
    Yohanes Santoso, Nov 3, 2004
    #2
    1. Advertising

  3. Thanks thats quite neat.

    On Wed, 3 Nov 2004 13:20:28 +0900, Yohanes Santoso
    <-a-geek.org> wrote:
    > Logan Capaldo <> writes:
    >
    >
    >
    > > Allright here was my idea which seems to have been shattered by the
    > > realities of Ruby.
    > >
    > > I was thinking of a class called Try. You would do something like
    > >
    > > class Try
    > > ...
    > > end
    > >
    > > tryblock = Try.new { #This block would normally be wrapped in a begin...rescue
    > > }
    > >
    > > tryblock.add_exhandler:)SomeException) { |ex| some_code }
    > >
    > > tryblock.execute #or possibly tryblock.call ?
    > >
    > > Basically the idea was going to be you could subclass Try and provide
    > > default sensible handling of your Exceptions (if you were writing a
    > > library for instance) . Users could then then wrap it in a
    > > begin...rescue block to catch other exceptions or use add_exhandler to
    > > overide the default handler. (Possibly provide a way to get the old
    > > handler and and use it in the new).
    > >
    > > my idea was going to be that I could do something like
    > >

    >
    > class Try
    > def execute
    > begin
    > user_proc.call(*user_proc_args)
    > rescue Error => e
    > elt = (exhandlers.select{|obj| e.class == obj.exception_class})[0]
    > if elt
    > elt.exception_handler.call(e)
    > else
    > raise e
    > end
    > end
    > end
    > end
    >
    >
    > YS.
    >
    >
    Logan Capaldo, Nov 3, 2004
    #3
  4. "Logan Capaldo" <> schrieb im Newsbeitrag
    news:...
    > Thanks thats quite neat.
    >
    > On Wed, 3 Nov 2004 13:20:28 +0900, Yohanes Santoso
    > <-a-geek.org> wrote:
    > > Logan Capaldo <> writes:
    > >
    > >
    > >
    > > > Allright here was my idea which seems to have been shattered by the
    > > > realities of Ruby.
    > > >
    > > > I was thinking of a class called Try. You would do something like
    > > >
    > > > class Try
    > > > ...
    > > > end
    > > >
    > > > tryblock = Try.new { #This block would normally be wrapped in a

    begin...rescue
    > > > }
    > > >
    > > > tryblock.add_exhandler:)SomeException) { |ex| some_code }
    > > >
    > > > tryblock.execute #or possibly tryblock.call ?
    > > >
    > > > Basically the idea was going to be you could subclass Try and

    provide
    > > > default sensible handling of your Exceptions (if you were writing a
    > > > library for instance) . Users could then then wrap it in a
    > > > begin...rescue block to catch other exceptions or use add_exhandler

    to
    > > > overide the default handler. (Possibly provide a way to get the old
    > > > handler and and use it in the new).
    > > >
    > > > my idea was going to be that I could do something like
    > > >

    > >
    > > class Try
    > > def execute
    > > begin
    > > user_proc.call(*user_proc_args)
    > > rescue Error => e
    > > elt = (exhandlers.select{|obj| e.class ==

    obj.exception_class})[0]
    > > if elt
    > > elt.exception_handler.call(e)
    > > else
    > > raise e
    > > end
    > > end
    > > end
    > > end


    We can save three more lines :)

    class Try
    def execute
    begin
    user_proc.call(*user_proc_args)
    rescue Error => e
    elt = (exhandlers.select{|obj| e.class == obj.exception_class})[0]
    raise unless elt
    elt.exception_handler.call(e)
    end
    end
    end

    Kind regards

    robert
    Robert Klemme, Nov 3, 2004
    #4
  5. In article <>, Robert Klemme wrote:
    >
    >"Logan Capaldo" <> schrieb im Newsbeitrag
    >news:...
    >> Thanks thats quite neat.
    >>
    >> On Wed, 3 Nov 2004 13:20:28 +0900, Yohanes Santoso
    >> <-a-geek.org> wrote:
    >> > Logan Capaldo <> writes:
    >> >
    >> >
    >> >
    >> > > Allright here was my idea which seems to have been shattered by the
    >> > > realities of Ruby.
    >> > >
    >> > > I was thinking of a class called Try. You would do something like
    >> > >
    >> > > class Try
    >> > > ...
    >> > > end
    >> > >
    >> > > tryblock = Try.new { #This block would normally be wrapped in a

    >begin...rescue
    >> > > }
    >> > >
    >> > > tryblock.add_exhandler:)SomeException) { |ex| some_code }
    >> > >
    >> > > tryblock.execute #or possibly tryblock.call ?
    >> > >
    >> > > Basically the idea was going to be you could subclass Try and

    >provide
    >> > > default sensible handling of your Exceptions (if you were writing a
    >> > > library for instance) . Users could then then wrap it in a
    >> > > begin...rescue block to catch other exceptions or use add_exhandler

    >to
    >> > > overide the default handler. (Possibly provide a way to get the old
    >> > > handler and and use it in the new).
    >> > >
    >> > > my idea was going to be that I could do something like
    >> > >
    >> >
    >> > class Try
    >> > def execute
    >> > begin
    >> > user_proc.call(*user_proc_args)
    >> > rescue Error => e
    >> > elt = (exhandlers.select{|obj| e.class ==

    >obj.exception_class})[0]
    >> > if elt
    >> > elt.exception_handler.call(e)
    >> > else
    >> > raise e
    >> > end
    >> > end
    >> > end
    >> > end

    >
    >We can save three more lines :)
    >
    >class Try
    > def execute
    > begin
    > user_proc.call(*user_proc_args)
    > rescue Error => e
    > elt = (exhandlers.select{|obj| e.class == obj.exception_class})[0]
    > raise unless elt
    > elt.exception_handler.call(e)
    > end
    > end
    >end


    As long as we're saving lines...

    class Try
    def execute
    user_proc.call(*user_proc_args)
    rescue Error => e
    elt = (exhandlers.select{|obj| e.class == obj.exception_class})[0] or raise
    elt.exception_handler.call(e)
    end
    end
    Tim Sutherland, Nov 3, 2004
    #5
  6. "Tim Sutherland" <> schrieb im Newsbeitrag
    news:...
    > In article <>, Robert Klemme wrote:
    > >
    > >"Logan Capaldo" <> schrieb im Newsbeitrag
    > >news:...
    > >> Thanks thats quite neat.
    > >>
    > >> On Wed, 3 Nov 2004 13:20:28 +0900, Yohanes Santoso
    > >> <-a-geek.org> wrote:
    > >> > Logan Capaldo <> writes:
    > >> >
    > >> >
    > >> >
    > >> > > Allright here was my idea which seems to have been shattered by

    the
    > >> > > realities of Ruby.
    > >> > >
    > >> > > I was thinking of a class called Try. You would do something like
    > >> > >
    > >> > > class Try
    > >> > > ...
    > >> > > end
    > >> > >
    > >> > > tryblock = Try.new { #This block would normally be wrapped in a

    > >begin...rescue
    > >> > > }
    > >> > >
    > >> > > tryblock.add_exhandler:)SomeException) { |ex| some_code }
    > >> > >
    > >> > > tryblock.execute #or possibly tryblock.call ?
    > >> > >
    > >> > > Basically the idea was going to be you could subclass Try and

    > >provide
    > >> > > default sensible handling of your Exceptions (if you were writing

    a
    > >> > > library for instance) . Users could then then wrap it in a
    > >> > > begin...rescue block to catch other exceptions or use

    add_exhandler
    > >to
    > >> > > overide the default handler. (Possibly provide a way to get the

    old
    > >> > > handler and and use it in the new).
    > >> > >
    > >> > > my idea was going to be that I could do something like
    > >> > >
    > >> >
    > >> > class Try
    > >> > def execute
    > >> > begin
    > >> > user_proc.call(*user_proc_args)
    > >> > rescue Error => e
    > >> > elt = (exhandlers.select{|obj| e.class ==

    > >obj.exception_class})[0]
    > >> > if elt
    > >> > elt.exception_handler.call(e)
    > >> > else
    > >> > raise e
    > >> > end
    > >> > end
    > >> > end
    > >> > end

    > >
    > >We can save three more lines :)
    > >
    > >class Try
    > > def execute
    > > begin
    > > user_proc.call(*user_proc_args)
    > > rescue Error => e
    > > elt = (exhandlers.select{|obj| e.class ==

    obj.exception_class})[0]
    > > raise unless elt
    > > elt.exception_handler.call(e)
    > > end
    > > end
    > >end

    >
    > As long as we're saving lines...
    >
    > class Try
    > def execute
    > user_proc.call(*user_proc_args)
    > rescue Error => e
    > elt = (exhandlers.select{|obj| e.class == obj.exception_class})[0]

    or raise
    > elt.exception_handler.call(e)
    > end
    > end


    Ha! Very nice indeed! Didn't think of that one. :)

    robert
    Robert Klemme, Nov 3, 2004
    #6
  7. "Robert Klemme" <> writes:

    >> class Try
    >> def execute
    >> user_proc.call(*user_proc_args)
    >> rescue Error => e
    >> elt = (exhandlers.select{|obj| e.class == obj.exception_class})[0]

    > or raise
    >> elt.exception_handler.call(e)
    >> end
    >> end


    Nice! But I think I have left out an important factor in the original
    solution. It shouldn't be e.class == obj.exception_class, but rather
    e.kind_of?(obj.exception_class).

    YS.
    Yohanes Santoso, Nov 4, 2004
    #7
  8. Logan Capaldo

    Zach Dennis Guest

    rescuing exceptions

    I'm doing some automated ftp'ing....

    begin
    #ftp code here
    rescue Net::FTPPermError => e
    #do nothing for example sake
    end

    Even though I rescue the Net::FTPPermError, it still makes it to $stderr
    if there is an error. What am I missing here? I have tried to rescue all
    Exceptions, etc..and it still gets printed. Looking at the code for
    chdir we have:

    def chdir(dirname)
    if dirname == ".."
    begin
    voidcmd("CDUP")
    return
    rescue FTPPermError
    if $![0, 3] != "500"
    raise FTPPermError, $!
    end
    end
    end
    cmd = "CWD " + dirname
    voidcmd(cmd)
    end

    If I try to use chdir in my example above to a bogus directory it still
    gets printed to $stderr, even though my rescue clause picks it up.
    Shouldn't that be the end of it?

    Thanks,


    Zach
    Zach Dennis, Nov 4, 2004
    #8
  9. Logan Capaldo

    benny Guest

    Re: completing the puzzle

    dear list,

    maybe I am a bit dump, but the code was only a part of the solution, right?

    so I tried to paint the rest of the picture and this was the only way I
    could figure out how the "core" may fit into the rest.
    (some classes and Try#initialize and Try#add_exhandler were missing,
    exhandlers is now attribute etc.)

    I'm just curious if this was the way you all thought about it or if I did
    miss an easier solution .

    regards,
    benny

    ######## the code ###########
    # general error class
    class Error < RuntimeError
    attr_accessor :exception_handler
    def initialize(code)
    code.call(self)
    end
    end

    # some specific self defined error class
    class TestError < Error
    attr_accessor :msg
    def initialize(msg = nil , &code)
    super(code) if code
    @msg = msg
    end
    end

    # the Try class
    class Try

    def initialize(*args, &code)
    @user_proc = code
    @user_proc_args = *args
    @exhandlers = []
    end

    def add_exhandler(name, &block)
    eval("@exhandlers << #{name.to_s}.new() do |obj| obj.exception_handler =
    block; end")
    end

    def execute
    @user_proc.call(@user_proc_args)
    rescue Error => e
    elt = (@exhandlers.select{|obj| e.kind_of? obj.class })[0] or raise
    elt.exception_handler.call(e)
    end
    end

    ######################
    # a test
    tryblock = Try.new {
    puts "doing something..."
    raise TestError, "my favorite error message"
    #raise "some other error"
    }

    tryblock.add_exhandler:)TestError) { | ex |
    puts "TestError raised!
    \n\tbacktrace:#{ex.backtrace}\n\tmessage:'#{ex.msg}'"
    }

    tryblock.execute







    Yohanes Santoso wrote:

    > "Robert Klemme" <> writes:
    >
    >>> class Try
    >>> def execute
    >>> user_proc.call(*user_proc_args)
    >>> rescue Error => e
    >>> elt = (exhandlers.select{|obj| e.class == obj.exception_class})[0]

    >> or raise
    >>> elt.exception_handler.call(e)
    >>> end
    >>> end

    >
    > Nice! But I think I have left out an important factor in the original
    > solution. It shouldn't be e.class == obj.exception_class, but rather
    > e.kind_of?(obj.exception_class).
    >
    > YS.
    benny, Nov 4, 2004
    #9
  10. Logan Capaldo

    benny Guest

    Re: completing the puzzle

    benny wrote:

    > maybe I am a bit dump

    Indeed, I am: that was to be proven. I meant "dumb" of course.

    benny
    benny, Nov 4, 2004
    #10
  11. Logan Capaldo

    Zach Dennis Guest

    Re: rescuing exceptions

    I haven't seen a reply to this thread, so I'll give it one more go.....

    When I rescue an Exception shouldn't it be my responsiblity as the
    developer to handle it and print it to STDOUT or STDERR? Why does Ruby
    1.8.2 still output something to STDERR!!? Is this just how it works?

    Zach

    ----CODE-----
    class MyException < Exception; end

    def method
    raise MyException
    end

    begin
    method
    rescue MyException
    #shouldn't this rescue the error?
    # --Why does it still get outputted to my screen?
    end
    Zach Dennis, Nov 5, 2004
    #11
  12. Re: rescuing exceptions

    Zach Dennis wrote:
    > I haven't seen a reply to this thread, so I'll give it one more go.....
    >
    > When I rescue an Exception shouldn't it be my responsiblity as the
    > developer to handle it and print it to STDOUT or STDERR? Why does Ruby
    > 1.8.2 still output something to STDERR!!? Is this just how it works?
    >
    > Zach
    >
    > ----CODE-----
    > class MyException < Exception; end
    >
    > def method
    > raise MyException
    > end
    >
    > begin
    > method
    > rescue MyException
    > #shouldn't this rescue the error?
    > # --Why does it still get outputted to my screen?
    > end


    Are you sure that code, exactly, prints something to stderr or stdout? I
    can't reproduce it here with 1.8.2 or 1.9 snapshots.
    Joel VanderWerf, Nov 5, 2004
    #12
  13. Logan Capaldo

    Zach Dennis Guest

    Re: rescuing exceptions

    Joel VanderWerf wrote:

    > Zach Dennis wrote:
    >
    >> I haven't seen a reply to this thread, so I'll give it one more go.....
    >>
    >> When I rescue an Exception shouldn't it be my responsiblity as the
    >> developer to handle it and print it to STDOUT or STDERR? Why does
    >> Ruby 1.8.2 still output something to STDERR!!? Is this just how it
    >> works?
    >>
    >> Zach
    >>
    >> ----CODE-----
    >> class MyException < Exception; end
    >>
    >> def method
    >> raise MyException
    >> end
    >>
    >> begin
    >> method
    >> rescue MyException
    >> #shouldn't this rescue the error?
    >> # --Why does it still get outputted to my screen?
    >> end

    >
    >
    > Are you sure that code, exactly, prints something to stderr or stdout?
    > I can't reproduce it here with 1.8.2 or 1.9 snapshots.


    Joel you are a lifesaver. Thank you for responding....I stepped out of
    my IDE shell and test just via command line. And you are correct, it
    doesn't print to stdout or stderr. So then I looked at the difference
    between how my IDE was running Ruby and me personally on the CLI. The
    debug "-d" option made the difference when calling Ruby. Bah, I guess
    that is what happens when you get real comfortable in an IDE.

    Thanks so much Joel for responding, otherwise I'd probably still be at
    this minor roadblock tomorrow!

    Zach
    Zach Dennis, Nov 5, 2004
    #13
    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. Marina
    Replies:
    2
    Views:
    467
    Marina
    Jul 8, 2003
  2. Amil Hanish
    Replies:
    0
    Views:
    539
    Amil Hanish
    Apr 13, 2006
  3. Adam H. Peterson

    Try blocks and not catching exceptions

    Adam H. Peterson, Jan 27, 2004, in forum: C++
    Replies:
    8
    Views:
    404
    Andrey Tarasevich
    Jan 27, 2004
  4. Paul Sijben
    Replies:
    5
    Views:
    368
    Gabriel Genellina
    Mar 8, 2007
  5. Chris Hare
    Replies:
    0
    Views:
    227
    Chris Hare
    Aug 5, 2010
Loading...

Share This Page