raise and rescue

Discussion in 'Ruby' started by Misiek Sz, Jun 13, 2008.

  1. Misiek Sz

    Misiek Sz Guest

    Is is possible to raise an exception then rescue it and then go back to
    whereever it was raised and continue with execution?
    For example,
    class Test
    end

    begin
    code line 1
    code line 2
    code line 3
    code line 4
    code line 5
    raise Class.new
    code line 7
    code line 8
    code line 9

    rescue Class
    #here in some cases send back execution to code line 7

    ensure
    end



    Thanks.
    --
    Posted via http://www.ruby-forum.com/.
    Misiek Sz, Jun 13, 2008
    #1
    1. Advertising

  2. On Fri, Jun 13, 2008 at 2:58 PM, Misiek Sz <> wrote:
    > Is is possible to raise an exception then rescue it and then go back to
    > wherever it was raised and continue with execution?


    No.

    Daniel Brumbaugh Keeney
    Daniel Brumbaugh Keeney, Jun 13, 2008
    #2
    1. Advertising

  3. [Note: parts of this message were removed to make it a legal post.]

    You _might_ be able to achieve something like that with an in-line rescue
    though. Like...

    code line 1
    code line 2
    code line 3
    code line 4
    code line 5
    raise Class.new rescue some_method_to_cope
    code line 7
    code line 8
    code line 9

    James

    On Fri, Jun 13, 2008 at 4:48 PM, Daniel Brumbaugh Keeney <
    > wrote:

    > On Fri, Jun 13, 2008 at 2:58 PM, Misiek Sz <> wrote:
    > > Is is possible to raise an exception then rescue it and then go back to
    > > wherever it was raised and continue with execution?

    >
    > No.
    >
    > Daniel Brumbaugh Keeney
    >
    >
    James Herdman, Jun 13, 2008
    #3
  4. On 13.06.2008 21:58, Misiek Sz wrote:
    > Is is possible to raise an exception then rescue it and then go back to
    > whereever it was raised and continue with execution?
    > For example,
    > class Test
    > end
    >
    > begin
    > code line 1
    > code line 2
    > code line 3
    > code line 4
    > code line 5
    > raise Class.new
    > code line 7
    > code line 8
    > code line 9
    >
    > rescue Class
    > #here in some cases send back execution to code line 7
    >
    > ensure
    > end


    There is no way - and for good reason. An exception is thrown because
    execution cannot proceed at that line.

    There is however retry, but it will continue from the beginning of the
    block:

    irb(main):001:0> i = 0
    => 0
    irb(main):002:0> begin
    irb(main):003:1* puts 1
    irb(main):004:1> raise "Foo"
    irb(main):005:1> rescue Exception
    irb(main):006:1> puts 2
    irb(main):007:1> i += 1
    irb(main):008:1> retry if i < 3
    irb(main):009:1> end
    1
    2
    1
    2
    1
    2
    => nil
    irb(main):010:0>

    Kind regards

    robert
    Robert Klemme, Jun 13, 2008
    #4
  5. Robert Klemme wrote:
    > On 13.06.2008 21:58, Misiek Sz wrote:
    >> Is is possible to raise an exception then rescue it and then go back to
    >> whereever it was raised and continue with execution?
    >> For example,
    >> class Test
    >> end
    >>
    >> begin
    >> code line 1
    >> code line 2
    >> code line 3
    >> code line 4
    >> code line 5
    >> raise Class.new
    >> code line 7
    >> code line 8
    >> code line 9
    >>
    >> rescue Class
    >> #here in some cases send back execution to code line 7
    >>
    >> ensure
    >> end

    >
    > There is no way - and for good reason. An exception is thrown because
    > execution cannot proceed at that line.
    >


    So how would you do something that requires user intervention, say in
    putting more paper in a printer? A lot of my programs require files or
    other resources that may not always be available and I have programmed
    them so that an error message is displayed and the operator can fix the
    problem and continue or abort the program. A very good example is when
    a user tries to bring up an account that is in use by another user. The
    program states that the record is busy and the operator can wait for the
    record to be freed and continue or go to another account.
    I can see how to do this in Ruby by using something like a while loop
    but that requires that the code surround every possible trouble spot
    rather than having a "generic" exception handling routine like I
    currently use in Business Basic.


    > There is however retry, but it will continue from the beginning of the
    > block:
    >
    > irb(main):001:0> i = 0
    > => 0
    > irb(main):002:0> begin
    > irb(main):003:1* puts 1
    > irb(main):004:1> raise "Foo"
    > irb(main):005:1> rescue Exception
    > irb(main):006:1> puts 2
    > irb(main):007:1> i += 1
    > irb(main):008:1> retry if i < 3
    > irb(main):009:1> end
    > 1
    > 2
    > 1
    > 2
    > 1
    > 2
    > => nil
    > irb(main):010:0>
    >
    > Kind regards
    >
    > robert
    Michael W. Ryder, Jun 13, 2008
    #5
  6. On Fri, Jun 13, 2008 at 5:34 PM, Michael W. Ryder
    <> wrote:
    > So how would you do something that requires user intervention, say in
    > putting more paper in a printer?


    def foo
    do_something



    Daniel Brumbaugh Keeney
    Daniel Brumbaugh Keeney, Jun 14, 2008
    #6
  7. On Fri, Jun 13, 2008 at 5:34 PM, Michael W. Ryder
    <> wrote:
    > So how would you do something that requires user intervention, say in
    > putting more paper in a printer?


    def foo
    do_something
    ensure_printer
    do_more
    end
    def ensure_printer
    return true if printer_available?
    if confirm 'you're printer has no paper. Try again?'
    ensure_printer
    else
    raise NoPaperError
    end
    end

    That's how I would imagine your problem to look. If there isn't paper,
    then it asks the user whether to try again, otherwise, it throws a
    NoPaperError which gets handled somewhere.

    Daniel Brumbaugh Keeney
    Daniel Brumbaugh Keeney, Jun 14, 2008
    #7
  8. Daniel Brumbaugh Keeney wrote:
    > On Fri, Jun 13, 2008 at 5:34 PM, Michael W. Ryder
    > <> wrote:
    >> So how would you do something that requires user intervention, say in
    >> putting more paper in a printer?

    >
    > def foo
    > do_something
    >
    >

    Maybe I am missing the point here but it doesn't appear that it would do
    what I have been doing for over 20 years with Business Basic. There I
    enter a line saying SETERR 9200 at the beginning of the program and the
    program automatically goes to that line when an error occurs anywhere in
    the program. From there I can display a message saying what is wrong
    and the operator can fix the problem and continue with the program or
    abort the program.
    Your example seems to require that I call a method anytime I run into a
    problem. This would seem to require that each possible problem area be
    surrounded by a while loop much like I have done in C.

    >
    > Daniel Brumbaugh Keeney
    >
    Michael W. Ryder, Jun 14, 2008
    #8
  9. Misiek Sz

    Guest

    On Jun 13, 6:25 pm, "Michael W. Ryder" <>
    wrote:

    > Maybe I am missing the point here but it doesn't appear that it would do
    > what I have been doing for over 20 years with Business Basic.  There I
    > enter a line saying SETERR 9200 at the beginning of the program and the
    > program automatically goes to that line when an error occurs anywhere in
    > the program.  From there I can display a message saying what is wrong
    > and the operator can fix the problem and continue with the program or
    > abort the program.


    That's true, and one of the trade-offs inherent to switching error
    handling from a GOTO control structure to a scoped control structure
    (such as bounded exception handling). The disadvantage is, as you've
    explained, that each problem area must be contained within its own
    error handling scope. The overwhelming advantage is that by catching
    errors as close to their occurrence as possible, it becomes much
    easier to identify just what went wrong, or pass the responsibility up
    to the next thing that can. Exceptions were invented to help
    programmers manage the complexity of handling errors.

    > Your example seems to require that I call a method anytime I run into a
    > problem.  This would seem to require that each possible problem area be
    > surrounded by a while loop much like I have done in C.


    It is possible to catch all (most) exceptions by placing your entire
    program in a begin-rescue block, and the rescue procedure would
    approximate what happens in the BASIC interrupt method. But if you do
    that, the disadvantage to the BASIC approach might become clear as you
    try to recover from the error. You'll have to know where to continue
    execution, as well as make sure that the rest of the application is in
    a similar state as it was before the error interrupted it.

    For a good description of the topic, check this out: http://stevemcconnell.com/ccgoto.htm

    I hope this helps, and good luck with your project!
    , Jun 14, 2008
    #9
  10. On 14.06.2008 00:31, Michael W. Ryder wrote:
    > Robert Klemme wrote:


    >> There is no way - and for good reason. An exception is thrown because
    >> execution cannot proceed at that line.

    >
    > So how would you do something that requires user intervention, say in
    > putting more paper in a printer? A lot of my programs require files or
    > other resources that may not always be available and I have programmed
    > them so that an error message is displayed and the operator can fix the
    > problem and continue or abort the program.


    That's exactly the case where /retry/ is meant for. Catch the
    exception, do something and then retry the block of code (see the
    example I posted earlier).

    > A very good example is when
    > a user tries to bring up an account that is in use by another user. The
    > program states that the record is busy and the operator can wait for the
    > record to be freed and continue or go to another account.
    > I can see how to do this in Ruby by using something like a while loop
    > but that requires that the code surround every possible trouble spot
    > rather than having a "generic" exception handling routine like I
    > currently use in Business Basic.


    See above.

    >> There is however retry, but it will continue from the beginning of the
    >> block:
    >>
    >> irb(main):001:0> i = 0
    >> => 0
    >> irb(main):002:0> begin
    >> irb(main):003:1* puts 1
    >> irb(main):004:1> raise "Foo"
    >> irb(main):005:1> rescue Exception
    >> irb(main):006:1> puts 2
    >> irb(main):007:1> i += 1
    >> irb(main):008:1> retry if i < 3
    >> irb(main):009:1> end
    >> 1
    >> 2
    >> 1
    >> 2
    >> 1
    >> 2
    >> => nil
    >> irb(main):010:0>


    Cheers

    robert
    Robert Klemme, Jun 14, 2008
    #10
  11. Misiek Sz

    Avdi Grimm Guest

    On Sat, Jun 14, 2008 at 6:43 AM, Michael T. Richter
    <> wrote:
    > 3. The exception handler pops up a dialogue/prompt/whatever telling me that
    > memory is low. It suggests actions I can take to free up enough memory.
    > Let's say I choose to kill memory hogs like Firefox or OpenOffice.org. I
    > click "continue" (or type or whatever the UI is).
    > 4. The exception handler retries the very line of code that failed. All of
    > the expensive, time-consuming setup that led to that point is still there
    > and still ready for action.


    If you really must do this and you're using 1.8, just throw the
    current continuation up the stack, and then resume it when when the
    memory issue is theoretically resolved.. I'm not going to go into
    detail, though, because a) I don't have time; and b) I'm going to be
    very opinionated here and say you really ought to be looking into
    better architecting your system to deal with memory crunches without
    these contortions, if you actually expect to be running out of memory
    a lot. However, look up calcc, and have fun.


    --
    Avdi

    Home: http://avdi.org
    Developer Blog: http://avdi.org/devblog/
    Twitter: http://twitter.com/avdi
    Journal: http://avdi.livejournal.com
    Avdi Grimm, Jun 14, 2008
    #11
    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. Jacol

    raise or not to raise [Newbie]

    Jacol, Feb 3, 2007, in forum: Python
    Replies:
    5
    Views:
    394
    Gabriel Genellina
    Feb 5, 2007
  2. ernest
    Replies:
    2
    Views:
    270
    Roy Smith
    Nov 14, 2010
  3. Jack Bates
    Replies:
    0
    Views:
    263
    Jack Bates
    May 2, 2011
  4. Mark Probert

    TCPSocket and rescue

    Mark Probert, Sep 4, 2003, in forum: Ruby
    Replies:
    2
    Views:
    113
    Mark Probert
    Sep 5, 2003
  5. bvdp

    Raise X or Raise X()?

    bvdp, Mar 11, 2012, in forum: Python
    Replies:
    10
    Views:
    343
    Stefan Behnel
    Mar 12, 2012
Loading...

Share This Page