# Raise and rescue

**URL:** <https://rubytalk.org/t/raise-and-rescue/47134>\
**Category:** ruby-talk\
**Created:** [13 June 2008 19:58 UTC](https://rubytalk.org/t/raise-and-rescue/47134 "2008-06-13T19:58:49Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michal\_Sza](https://avatars.discourse-cdn.com/v4/letter/m/6f9a4e/32.png) [@Michal\_Sza](https://rubytalk.org/u/Michal_Sza)\
**Post date:** [13 June 2008 19:58 UTC](https://rubytalk.org/t/raise-and-rescue/47134/1 "2008-06-13T19:58:49Z")

</div>

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/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Daniel\_Brumbaugh\_Kee](https://avatars.discourse-cdn.com/v4/letter/d/eb9ed0/32.png) [@Daniel\_Brumbaugh\_Kee](https://rubytalk.org/u/Daniel_Brumbaugh_Kee)\
**Post date:** [13 June 2008 20:48 UTC](https://rubytalk.org/t/raise-and-rescue/47134/2 "2008-06-13T20:48:54Z")

</div>

No.

Daniel Brumbaugh Keeney

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

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [13 June 2008 21:09 UTC](https://rubytalk.org/t/raise-and-rescue/47134/3 "2008-06-13T21:09:26Z")

</div>

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

&nbsp;&nbsp;robert

> **···**
>
> 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

---

<div class="post-metadata">

**Author:** ![Sylvain\_Joyeux](https://avatars.discourse-cdn.com/v4/letter/s/96bed5/32.png) [@Sylvain\_Joyeux](https://rubytalk.org/u/Sylvain_Joyeux)\
**Post date:** [14 June 2008 14:17 UTC](https://rubytalk.org/t/raise-and-rescue/47134/4 "2008-06-14T14:17:37Z")

</div>

There is no direct way, but you can implement it using continuations  
(would not be supported in 1.9 though ...)

See attached file

Sylvain

[restartable.rb](https://rubytalk.org/uploads/short-url/hzjYShb0gpBz5e64u9XZqlv3kH.rb) (862 Bytes)

---

<div class="post-metadata">

**Author:** ![James\_H](https://avatars.discourse-cdn.com/v4/letter/j/9de053/32.png) [@James\_H](https://rubytalk.org/u/James_H)\
**Post date:** [13 June 2008 21:06 UTC](https://rubytalk.org/t/raise-and-rescue/47134/5 "2008-06-13T21:06:50Z")

</div>

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 \< devi.webmaster@gmail.com\> wrote:
> 
> > On Fri, Jun 13, 2008 at 2:58 PM, Misiek Sz \<nicpon@nicpon.net\> 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

---

<div class="post-metadata">

**Author:** ![Michael\_W\_Ryder1](https://avatars.discourse-cdn.com/v4/letter/m/8e7dd6/32.png) [@Michael\_W\_Ryder1](https://rubytalk.org/u/Michael_W_Ryder1)\
**Post date:** [13 June 2008 22:34 UTC](https://rubytalk.org/t/raise-and-rescue/47134/6 "2008-06-13T22:34:32Z")

</div>

Robert Klemme 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.

> **···**
>
> > On 13.06.2008 21:58, Misiek Sz wrote:
> 
> > 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
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;robert

---

<div class="post-metadata">

**Author:** ![Michael\_T\_Richter](https://avatars.discourse-cdn.com/v4/letter/m/9d8465/32.png) [@Michael\_T\_Richter](https://rubytalk.org/u/Michael_T_Richter)\
**Post date:** [14 June 2008 10:43 UTC](https://rubytalk.org/t/raise-and-rescue/47134/7 "2008-06-14T10:43:19Z")

</div>

This is not a "good reason". Having used languages with restartable  
exceptions I can pretty much guarantee you that it is not only possible,  
but often desirable to have restartable exceptions. Consider this use  
case:

1. The software commences a procedure that is time-consuming and that  
requires lots of memory.  
2. In the middle of this it runs out of memory. An exception is raised.

In the Ruby (and many other languages) world, I'm boned. I have to  
throw away all the time and memory spent to get where I am, free up  
memory in some way, and then restart the whole thing. This could be a  
non-trivial operation (and, indeed, for this use case, is defined as  
such). In a world with restartable exceptions, however, the use case  
continues thus:

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.

(Please note at this point that this is only one example. I could  
probably, given an hour, come up with a hundred situations in which  
restartable exceptions are useful and desirable. Too, the handler's  
actions are only one of a thousand possible reactions it could have.  
Maybe for efficiency's sake I'm memoizing a whole bunch of calculations.  
If I run out of memory in this case, the handler could clear the LRU  
memo cache entries for twice the amount of reported memory being claimed  
as a quick heuristic. This would be totally transparent to the user  
except for a slight hiccough in performance.)

Now it is possible in the Ruby model to partition things in many  
situations such that a retry only executes a small amount of code  
instead of the huge setup alluded to above. This is a problem, however,  
for several reasons:

1. You're putting in unnecessary scaffolding code solely because of the  
language's shortcomings. (Shades of C++ and Java here, albeit very,  
very, very minuscule shades.) This clutters code, constrains  
architecture and generally is, to my eyes, anti-Ruby.  
2. Not all problems can be built this way. For those problems which  
cannot be set up this way, you're boned.  
3. Most importantly, you're constraining your very thinking about  
problems. There will be approaches to problems you simply will not  
think of because the very language conspires against your thinking down  
those lines.

> **···**
>
> On Sat, 2008-06-14 at 06:09 +0900, Robert Klemme wrote:
> 
> > There is no way - and for good reason. An exception is thrown because  
> > execution cannot proceed at that line.
> 
> --  
> Michael T. Richter \<ttmrichter@gmail.com\> (GoogleTalk:  
> ttmrichter@gmail.com)  
> Politics is the art of looking for trouble, finding it whether it exists  
> or not, diagnosing it incorrectly, and applying the wrong remedy.  
> (Ernest Benn)

---

<div class="post-metadata">

**Author:** ![Daniel\_Brumbaugh\_Kee](https://avatars.discourse-cdn.com/v4/letter/d/eb9ed0/32.png) [@Daniel\_Brumbaugh\_Kee](https://rubytalk.org/u/Daniel_Brumbaugh_Kee)\
**Post date:** [13 June 2008 23:15 UTC](https://rubytalk.org/t/raise-and-rescue/47134/8 "2008-06-13T23:15:09Z")

</div>

def foo  
&nbsp;&nbsp;&nbsp;&nbsp;do\_something

Daniel Brumbaugh Keeney

> **···**
>
> On Fri, Jun 13, 2008 at 5:34 PM, Michael W. Ryder \<\_mwryder@worldnet.att.net\> wrote:
> 
> > So how would you do something that requires user intervention, say in  
> > putting more paper in a printer?

---

<div class="post-metadata">

**Author:** ![Daniel\_Brumbaugh\_Kee](https://avatars.discourse-cdn.com/v4/letter/d/eb9ed0/32.png) [@Daniel\_Brumbaugh\_Kee](https://rubytalk.org/u/Daniel_Brumbaugh_Kee)\
**Post date:** [13 June 2008 23:20 UTC](https://rubytalk.org/t/raise-and-rescue/47134/9 "2008-06-13T23:20:58Z")

</div>

def foo  
&nbsp;&nbsp;&nbsp;&nbsp;do\_something  
&nbsp;&nbsp;&nbsp;&nbsp;ensure\_printer  
&nbsp;&nbsp;&nbsp;&nbsp;do\_more  
end  
def ensure\_printer  
&nbsp;&nbsp;&nbsp;&nbsp;return true if printer\_available?  
&nbsp;&nbsp;&nbsp;&nbsp;if confirm 'you're printer has no paper. Try again?'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ensure\_printer  
&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise NoPaperError  
&nbsp;&nbsp;&nbsp;&nbsp;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

> **···**
>
> On Fri, Jun 13, 2008 at 5:34 PM, Michael W. Ryder \<\_mwryder@worldnet.att.net\> wrote:
> 
> > So how would you do something that requires user intervention, say in  
> > putting more paper in a printer?

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [14 June 2008 09:44 UTC](https://rubytalk.org/t/raise-and-rescue/47134/10 "2008-06-14T09:44:21Z")

</div>

> 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

&nbsp;&nbsp;robert

> **···**
>
> On 14.06.2008 00:31, Michael W. Ryder wrote:

---

<div class="post-metadata">

**Author:** ![Avdi\_Grimm1](https://avatars.discourse-cdn.com/v4/letter/a/e47c2d/32.png) [@Avdi\_Grimm1](https://rubytalk.org/u/Avdi_Grimm1)\
**Post date:** [14 June 2008 13:56 UTC](https://rubytalk.org/t/raise-and-rescue/47134/11 "2008-06-14T13:56:51Z")

</div>

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.

> **···**
>
> On Sat, Jun 14, 2008 at 6:43 AM, Michael T. Richter \<ttmrichter@gmail.com\> 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.
> 
> --  
> Avdi
> 
> Home: [http://avdi.org](http://avdi.org)  
> Developer Blog: [Avdi Grimm, Code Cleric](http://avdi.org/devblog/)  
> Twitter: [http://twitter.com/avdi](http://twitter.com/avdi)  
> Journal: [http://avdi.livejournal.com](http://avdi.livejournal.com)

---

<div class="post-metadata">

**Author:** ![Michael\_W\_Ryder1](https://avatars.discourse-cdn.com/v4/letter/m/8e7dd6/32.png) [@Michael\_W\_Ryder1](https://rubytalk.org/u/Michael_W_Ryder1)\
**Post date:** [13 June 2008 23:29 UTC](https://rubytalk.org/t/raise-and-rescue/47134/12 "2008-06-13T23:29:25Z")

</div>

Daniel Brumbaugh Keeney wrote:

> > So how would you do something that requires user intervention, say in  
> > putting more paper in a printer?
> 
> def foo  
> &nbsp;&nbsp;&nbsp;&nbsp;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.

> **···**
>
> > On Fri, Jun 13, 2008 at 5:34 PM, Michael W. Ryder \> \<\_mwryder@worldnet.att.net\> wrote:
> 
> > Daniel Brumbaugh Keeney

---

<div class="post-metadata">

**Author:** ![nicholasmabry](https://avatars.discourse-cdn.com/v4/letter/n/a5b964/32.png) [@nicholasmabry](https://rubytalk.org/u/nicholasmabry)\
**Post date:** [14 June 2008 01:39 UTC](https://rubytalk.org/t/raise-and-rescue/47134/13 "2008-06-14T01:39:23Z")

</div>

> 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: [Books | Steve McConnell](http://stevemcconnell.com/ccgoto.htm)

I hope this helps, and good luck with your project!

> **···**
>
> On Jun 13, 6:25 pm, "Michael W. Ryder" \<\_mwry...@worldnet.att.net\> wrote:
