# MRI 1.8.6 bug - exit is ignored if ensure clause throws exception which is caught by outer rescue

**URL:** <https://www.ruby-forum.com/t/mri-1-8-6-bug-exit-is-ignored-if-ensure-clause-throws-exception-which-is-caught-by-outer-rescue/157535>\
**Category:** IronRuby\
**Created:** [January 12, 2009, 9:33pm UTC](https://www.ruby-forum.com/t/mri-1-8-6-bug-exit-is-ignored-if-ensure-clause-throws-exception-which-is-caught-by-outer-rescue/157535 "2009-01-12T21:33:42Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Shri\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/898d66/32.png) [@Shri\_B](https://www.ruby-forum.com/u/Shri_B)\
**Post date:** [January 12, 2009, 9:33pm UTC](https://www.ruby-forum.com/t/mri-1-8-6-bug-exit-is-ignored-if-ensure-clause-throws-exception-which-is-caught-by-outer-rescue/157535/1 "2009-01-12T21:33:42Z")

</div>

The following code snippet does print “after foo” when using MRI 1.8.6  
on Windows Vista, showing that exit is ignored. Any thoughts on whether  
this is by design, a known bug, or a new issue? If it’s the latter,  
should I open a bug for it?

def foo  
begin  
begin  
begin  
exit  
rescue  
puts “We never reach here”  
end  
ensure  
raise “exception from ensure”  
end  
rescue  
puts “We do reach here, which is unexpected”  
end  
end

foo  
print “after foo”

Thanks,  
Shri

---

<div class="post-metadata">

**Author:** ![Shri\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/898d66/32.png) [@Shri\_B](https://www.ruby-forum.com/u/Shri_B)\
**Post date:** [January 12, 2009, 10:02pm UTC](https://www.ruby-forum.com/t/mri-1-8-6-bug-exit-is-ignored-if-ensure-clause-throws-exception-which-is-caught-by-outer-rescue/157535/2 "2009-01-12T22:02:07Z")

</div>

On Jan 12, 2009, at 12:31 PM, Shri B. wrote:

> The following code snippet does print â€œafter fooâ€ when using MRI  
> 1.8.6 on Windows Vista, showing that exit is ignored. Any thoughts  
> on whether this is by design, a known bug, or a new issue? If itâ€™s  
> the latter, should I open a bug for it?

No, this is by design. Kernel#exit raises SystemExit, which the  
toplevel rescues and performs the actual exit. If you raise a new  
exception in the ensure. the SystemExit exception is never seen by the  
toplevel, and thus you don’t get the exit.

This is used in a few places to cause exit to be ignored, or to allow  
a library to convert a SystemExit exception into something else  
(perhaps an IllegalOperation or something).

- Evan P.

---

<div class="post-metadata">

**Author:** ![Shri\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/898d66/32.png) [@Shri\_B](https://www.ruby-forum.com/u/Shri_B)\
**Post date:** [January 12, 2009, 10:35pm UTC](https://www.ruby-forum.com/t/mri-1-8-6-bug-exit-is-ignored-if-ensure-clause-throws-exception-which-is-caught-by-outer-rescue/157535/3 "2009-01-12T22:35:07Z")

</div>

I believe this is by design. Exit throws an exception (SystemExit). The  
exception is not rescued by a default rescue clause because it doesn’t  
derive from StandardError. Thus the raise in ensure gets called and it  
raises RuntimeError which gets caught in the outer rescue because  
RuntimeError \<: StandardError.

Tomas

From: Shri B. [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]  
Sent: Monday, January 12, 2009 12:32 PM  
To: removed\_email\_address@domain.invalid; removed\_email\_address@domain.invalid  
Subject: [ruby-core:21289] MRI 1.8.6 bug - exit is ignored if ensure  
clause throws exception which is caught by outer rescue

The following code snippet does print “after foo” when using MRI 1.8.6  
on Windows Vista, showing that exit is ignored. Any thoughts on whether  
this is by design, a known bug, or a new issue? If it’s the latter,  
should I open a bug for it?

def foo  
begin  
begin  
begin  
exit  
rescue  
puts “We never reach here”  
end  
ensure  
raise “exception from ensure”  
end  
rescue  
puts “We do reach here, which is unexpected”  
end  
end

foo  
print “after foo”

Thanks,  
Shri

---

<div class="post-metadata">

**Author:** ![Shri\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/898d66/32.png) [@Shri\_B](https://www.ruby-forum.com/u/Shri_B)\
**Post date:** [January 12, 2009, 11:10pm UTC](https://www.ruby-forum.com/t/mri-1-8-6-bug-exit-is-ignored-if-ensure-clause-throws-exception-which-is-caught-by-outer-rescue/157535/4 "2009-01-12T23:10:40Z")

</div>

OK, I have added a RSpec test, and have already tagged it as an  
IronRuby bug.

For reference, .NET allows the equivalent ThreadAbortException to be  
caught, but automatically rethrows it at the end of the catch/rescue  
block. The programmer is required to take a separate action (calling  
Thread.ResetAbort[http://msdn.microsoft.com/en-us/library/system.threading.thread.resetabort.aspx](http://msdn.microsoft.com/en-us/library/system.threading.thread.resetabort.aspx))  
to complete cancel the abort operation. This prevents situations where  
one component triggers the abort, and another cancels it unintentially.  
In theory, you should always do “rescue SomeSpecificExceptionType”, but  
a lot of people do use just “rescue”.

From: Evan P. [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]  
Sent: Monday, January 12, 2009 1:01 PM  
To: removed\_email\_address@domain.invalid  
Subject: [ruby-core:21290] Re: MRI 1.8.6 bug - exit is ignored if ensure  
clause throws exception which is caught by outer rescue

On Jan 12, 2009, at 12:31 PM, Shri B. wrote:

The following code snippet does print “after foo” when using MRI 1.8.6  
on Windows Vista, showing that exit is ignored. Any thoughts on whether  
this is by design, a known bug, or a new issue? If it’s the latter,  
should I open a bug for it?

No, this is by design. Kernel#exit raises SystemExit, which the toplevel  
rescues and performs the actual exit. If you raise a new exception in  
the ensure. the SystemExit exception is never seen by the toplevel, and  
thus you don’t get the exit.

This is used in a few places to cause exit to be ignored, or to allow a  
library to convert a SystemExit exception into something else (perhaps  
an IllegalOperation or something).

- Evan P.

def foo  
begin  
begin  
begin  
exit  
rescue  
puts “We never reach here”  
end  
ensure  
raise “exception from ensure”  
end  
rescue  
puts “We do reach here, which is unexpected”  
end  
end

foo  
print “after foo”

Thanks,  
Shri

---

<div class="post-metadata">

**Author:** ![Shri\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/898d66/32.png) [@Shri\_B](https://www.ruby-forum.com/u/Shri_B)\
**Post date:** [January 13, 2009, 12:03am UTC](https://www.ruby-forum.com/t/mri-1-8-6-bug-exit-is-ignored-if-ensure-clause-throws-exception-which-is-caught-by-outer-rescue/157535/5 "2009-01-13T00:03:01Z")

</div>

I was assuming that exit and Thread.current.kill do the same thing, but  
Tomas pointed out that they are different. Would you expect that “after  
foo” would get printed even if you replace exit with  
Thread.current.kill?

Thanks,  
Shri

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Shri B.  
Sent: Monday, January 12, 2009 2:10 PM  
To: removed\_email\_address@domain.invalid; removed\_email\_address@domain.invalid  
Subject: Re: [Ironruby-core] [ruby-core:21290] Re: MRI 1.8.6 bug - exit  
is ignored if ensure clause throws exception which is caught by outer  
rescue

OK, I have added a RSpec test, and have already tagged it as an  
IronRuby bug.

For reference, .NET allows the equivalent ThreadAbortException to be  
caught, but automatically rethrows it at the end of the catch/rescue  
block. The programmer is required to take a separate action (calling  
Thread.ResetAbort[http://msdn.microsoft.com/en-us/library/system.threading.thread.resetabort.aspx](http://msdn.microsoft.com/en-us/library/system.threading.thread.resetabort.aspx))  
to complete cancel the abort operation. This prevents situations where  
one component triggers the abort, and another cancels it unintentially.  
In theory, you should always do “rescue SomeSpecificExceptionType”, but  
a lot of people do use just “rescue”.

From: Evan P. [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]  
Sent: Monday, January 12, 2009 1:01 PM  
To: removed\_email\_address@domain.invalid  
Subject: [ruby-core:21290] Re: MRI 1.8.6 bug - exit is ignored if ensure  
clause throws exception which is caught by outer rescue

On Jan 12, 2009, at 12:31 PM, Shri B. wrote:

The following code snippet does print “after foo” when using MRI 1.8.6  
on Windows Vista, showing that exit is ignored. Any thoughts on whether  
this is by design, a known bug, or a new issue? If it’s the latter,  
should I open a bug for it?

No, this is by design. Kernel#exit raises SystemExit, which the toplevel  
rescues and performs the actual exit. If you raise a new exception in  
the ensure. the SystemExit exception is never seen by the toplevel, and  
thus you don’t get the exit.

This is used in a few places to cause exit to be ignored, or to allow a  
library to convert a SystemExit exception into something else (perhaps  
an IllegalOperation or something).

- Evan P.

def foo  
begin  
begin  
begin  
exit  
rescue  
puts “We never reach here”  
end  
ensure  
raise “exception from ensure”  
end  
rescue  
puts “We do reach here, which is unexpected”  
end  
end

foo  
print “after foo”

Thanks,  
Shri
