<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Simone Carletti&#039;s Blog &#187; exceptions</title>
	<atom:link href="http://www.simonecarletti.com/blog/tags/exceptions/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.simonecarletti.com/blog</link>
	<description>Simone Carletti&#039;s personal ramblings on programming, syndication, search engines &#38; marketing.</description>
	<lastBuildDate>Tue, 07 Feb 2012 08:48:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>How slow are (Ruby) Exceptions?</title>
		<link>http://www.simonecarletti.com/blog/2010/01/how-slow-are-ruby-exceptions/</link>
		<comments>http://www.simonecarletti.com/blog/2010/01/how-slow-are-ruby-exceptions/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 08:01:58 +0000</pubDate>
		<dc:creator>Simone Carletti</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[exceptions]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.simonecarletti.com/blog/?p=915</guid>
		<description><![CDATA[Some benchmarks to demonstrate how slow exceptions can be.]]></description>
			<content:encoded><![CDATA[<p>If you are used to <a href="http://www.simonecarletti.com/blog/2009/09/inside-ruby-on-rails-benchmarking-your-scripts/">benchmark your Ruby scripts</a> or if you ever had to improve the performance of some strategic tasks, then this post won&#8217;t tell you nothing new because you should already know that Exceptions are slow. And this is not really a Ruby problem: <a href="http://stackoverflow.com/questions/161942/how-slow-are-net-exceptions">.NET Exceptions are slow</a>, <a href="http://stackoverflow.com/questions/299068/how-slow-are-java-exceptions">JAVA Exceptions are slow</a> just because the begin/raise/rescue (or try/throw/catch) architecture is slow by nature.</p>
<p><strong>But how slow are Ruby Exceptions?</strong></p>
<p>The answer to this question really depends on how complex is your code. Here I just want to show you a very simple example, extracted from a really strategic <a href="http://www.robodomain.com/">RoboDomain DNS sorting algorithm</a>.<span id="more-915"></span></p>
<p><script src="http://gist.github.com/275768.js?file=if_vs_exception_vs_regexp.rb"></script></p>
<p>The code is fairly simple: the value for an <code>A</code> record is expected to be an IP Address while the value for a <code>NS</code> record is expected to be represented by a <abbr title="Fully Qualified Domain Name">FQDN</abbr> as string. The code should parse the <code>data</code> and return the normalized <code>value</code> depending on some conditions.</p>
<p>The first version of the algorithm is completely based on Exceptions. <code>IPAddr</code> raises an <code>ArgumentError</code> when the argument is not a valid IP Address. In this case, the script gracefully returns the value as string.</p>
<p>The second version checks against the record value (I agree with you that is quite empiric, but representative for the sake of this benchmark).</p>
<p>The third version is a less empiric alternative that uses some regular expressions to check whether the data looks like an IP before actually feeding the <code>IPAddr</code> class. Under the hood, the <code>IPAddr</code> class performs a really similar task, the only difference here is that in the latter case I&#8217;m not using Exceptions at all.</p>
<p>Results speak for themselves. *</p>
<p>(*) As pointed out by <cite>Curtis Summers</cite> in the comments,a huge amount of time is actually spent by <code>IPAddr</code> trying to resolve the hostname. For more benchmarks, also look at <a href="http://gist.github.com/275768#file_if_vs_exception_vs_regexp_zerodivision.rb">this test</a>.</p>
<p>With Ruby 1.8.7, the algorithm (note, this is a super-simplified version of the original algorithm) is <strong>about 37 times slower when Exceptions are involved</strong>.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ ruby if_vs_exception.rb<br />
Rehearsal ------------------------------------------------<br />
NS exception &nbsp; 4.330000 &nbsp; 5.750000 &nbsp;10.080000 ( 37.599575)<br />
NS if &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0.140000 &nbsp; 0.010000 &nbsp; 0.150000 ( &nbsp;0.136280)<br />
NS regexp &nbsp; &nbsp; &nbsp;0.450000 &nbsp; 0.000000 &nbsp; 0.450000 ( &nbsp;0.454040)<br />
A exception &nbsp; &nbsp;2.010000 &nbsp; 0.020000 &nbsp; 2.030000 ( &nbsp;2.047711)<br />
A if &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2.060000 &nbsp; 0.020000 &nbsp; 2.080000 ( &nbsp;2.074642)<br />
A regepx &nbsp; &nbsp; &nbsp; 2.030000 &nbsp; 0.020000 &nbsp; 2.050000 ( &nbsp;2.054930)<br />
-------------------------------------- total: 16.840000sec<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;user &nbsp; &nbsp; system &nbsp; &nbsp; &nbsp;total &nbsp; &nbsp; &nbsp; &nbsp;real<br />
NS exception &nbsp; 4.420000 &nbsp; 5.810000 &nbsp;10.230000 ( 38.350608)<br />
NS if &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0.130000 &nbsp; 0.000000 &nbsp; 0.130000 ( &nbsp;0.130863)<br />
NS regexp &nbsp; &nbsp; &nbsp;0.450000 &nbsp; 0.000000 &nbsp; 0.450000 ( &nbsp;0.447975)<br />
A exception &nbsp; &nbsp;2.000000 &nbsp; 0.020000 &nbsp; 2.020000 ( &nbsp;2.016231)<br />
A if &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2.020000 &nbsp; 0.020000 &nbsp; 2.040000 ( &nbsp;2.043085)<br />
A regepx &nbsp; &nbsp; &nbsp; 2.030000 &nbsp; 0.020000 &nbsp; 2.050000 ( &nbsp;2.048402)</div></td></tr></tbody></table></div>
<p>The same story with Ruby 1.9.1.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Rehearsal ------------------------------------------------<br />
NS exception &nbsp; 4.650000 &nbsp; 5.800000 &nbsp;10.450000 ( 39.134858)<br />
NS if &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0.080000 &nbsp; 0.000000 &nbsp; 0.080000 ( &nbsp;0.079427)<br />
NS regexp &nbsp; &nbsp; &nbsp;0.320000 &nbsp; 0.000000 &nbsp; 0.320000 ( &nbsp;0.320389)<br />
A exception &nbsp; &nbsp;1.180000 &nbsp; 0.010000 &nbsp; 1.190000 ( &nbsp;1.182892)<br />
A if &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1.200000 &nbsp; 0.000000 &nbsp; 1.200000 ( &nbsp;1.209433)<br />
A regepx &nbsp; &nbsp; &nbsp; 1.220000 &nbsp; 0.000000 &nbsp; 1.220000 ( &nbsp;1.219345)<br />
-------------------------------------- total: 14.460000sec<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;user &nbsp; &nbsp; system &nbsp; &nbsp; &nbsp;total &nbsp; &nbsp; &nbsp; &nbsp;real<br />
NS exception &nbsp; 4.520000 &nbsp; 5.720000 &nbsp;10.240000 ( 37.931455)<br />
NS if &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0.080000 &nbsp; 0.000000 &nbsp; 0.080000 ( &nbsp;0.078286)<br />
NS regexp &nbsp; &nbsp; &nbsp;0.320000 &nbsp; 0.000000 &nbsp; 0.320000 ( &nbsp;0.320988)<br />
A exception &nbsp; &nbsp;1.190000 &nbsp; 0.000000 &nbsp; 1.190000 ( &nbsp;1.186198)<br />
A if &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1.210000 &nbsp; 0.010000 &nbsp; 1.220000 ( &nbsp;1.220254)<br />
A regepx &nbsp; &nbsp; &nbsp; 1.220000 &nbsp; 0.000000 &nbsp; 1.220000 ( &nbsp;1.215634)</div></td></tr></tbody></table></div>
<p><strong>Does this mean I should forget about Exceptions?</strong></p>
<p>Absolutely no! I love Exceptions and you should love them too. However, <a href="http://robots.thoughtbot.com/post/159807850/save-bang-your-head-active-record-will-drive-you-mad">Exceptions should not be expected</a> and, in some circumstances, an <code>if</code> can be much more convenient, or at least, efficient.</p>
<p>One important lesson to learn from these benchmarks is that exceptions should not be part of the regular application flow. This shouldn&#8217;t prevent you to use them to handle unexpected situations and exception performance shouldn&#8217;t be a big deal in this case.</p>
<p>A lesson learned from this specific case, is to avoid using exceptions in place of conditional statements to handle not exceptional situations.</p>
<p><strong>UPDATE:</strong> for more interesting comments, check out the <a href="http://www.reddit.com/r/ruby/comments/ap33d/how_slow_are_ruby_exceptions/">Reddit page</a>.</p>
<p>Related posts<ol>
<li><a href='http://www.simonecarletti.com/blog/2009/11/re-raise-a-ruby-exception-in-a-rails-rescue_from-statement/' rel='bookmark' title='Re-raise a Ruby exception in a Rails rescue_from statement'>Re-raise a Ruby exception in a Rails rescue_from statement</a></li>
<li><a href='http://www.simonecarletti.com/blog/2010/09/introducing-public-suffix-service-0-5-0/' rel='bookmark' title='Introducing Public Suffix Service 0.5.0'>Introducing Public Suffix Service 0.5.0</a></li>
<li><a href='http://www.simonecarletti.com/blog/2009/12/inside-ruby-on-rails-rescuable-and-rescue_from/' rel='bookmark' title='Understanding Ruby and Rails: Rescuable and rescue_from'>Understanding Ruby and Rails: Rescuable and rescue_from</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.simonecarletti.com/blog/2010/01/how-slow-are-ruby-exceptions/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Understanding Ruby and Rails: Rescuable and rescue_from</title>
		<link>http://www.simonecarletti.com/blog/2009/12/inside-ruby-on-rails-rescuable-and-rescue_from/</link>
		<comments>http://www.simonecarletti.com/blog/2009/12/inside-ruby-on-rails-rescuable-and-rescue_from/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 08:00:34 +0000</pubDate>
		<dc:creator>Simone Carletti</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[activesupport]]></category>
		<category><![CDATA[exceptions]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rails 3]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.simonecarletti.com/blog/?p=842</guid>
		<description><![CDATA[How to use the ActiveSupport::Rescuable module in a Rails application and in your non-Rails Ruby code.]]></description>
			<content:encoded><![CDATA[<div class="flash-message info target-rails">
<p>This article targets <strong>Rails 2.3</strong> and <strong>Rails 3</strong>. The information contained in this page might not apply to different versions.</p>
</div>
<p><em>This is article is part of my series Understanding Ruby and Rails. Please see the <a href="http://www.simonecarletti.com/blog/2009/09/inside-ruby-on-rails-reading-source-code/">table of contents</a> for the series to view the list of all posts.</em></p>
<p>Last time I talked about the <code>ActiveSupport</code> <code>Module#delegate</code> method. Today, I want to introduce an other poweful <code>ActiveSupport</code> module: <code>Rescuable</code>, also known in the Rails ecosystem as <code><a title="Module: ActiveSupport::Rescuable::ClassMethods" href="http://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html">rescue_from</a></code>.<span id="more-842"></span></p>
<h2><code>rescue_from</code> and Rails</h2>
<p>Starting from the release 2.0, Rails provides <a title="Ryan's Scraps: What's New in Edge Rails: Better Exception Handling" href="http://ryandaigle.com/articles/2007/9/24/what-s-new-in-edge-rails-better-exception-handling">a clean way to rescue exceptions in a controller</a>, mapping specific error classes to corresponding handlers.</p>
<p>Let&#8217;s see an example. A call to <code>ActiveRecord#find</code> raises an <code>ActiveRecord::RecordNotFound</code> exception when the record passed as parameter doesn&#8217;t exist. Assuming you want to display a nice 404 error page, you need to rescue the exception in each action where a <code>find</code> call is performed.</p>
<div class="codecolorer-container text default code-ruby" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">class PostsController &lt; ApplicationController<br />
&nbsp; def show<br />
&nbsp; &nbsp; @post = Post.find(params[:id])<br />
&nbsp; rescue ActiveRecord::RecordNotFound<br />
&nbsp; &nbsp; render_404<br />
&nbsp; end<br />
<br />
&nbsp; def edit<br />
&nbsp; &nbsp; @post = Post.find(params[:id])<br />
&nbsp; rescue ActiveRecord::RecordNotFound<br />
&nbsp; &nbsp; render_404<br />
&nbsp; end<br />
<br />
&nbsp; def destroy<br />
&nbsp; &nbsp; @post = Post.find(params[:id])<br />
&nbsp; &nbsp; @post.destroy<br />
&nbsp; rescue ActiveRecord::RecordNotFound<br />
&nbsp; &nbsp; render_404<br />
&nbsp; end<br />
end<br />
<br />
class UserController &lt; ApplicationController<br />
&nbsp; def show<br />
&nbsp; &nbsp; @user = User.find(params[:id])<br />
&nbsp; rescue ActiveRecord::RecordNotFound<br />
&nbsp; &nbsp; render_404<br />
&nbsp; end<br />
<br />
&nbsp; # ...<br />
end</div></td></tr></tbody></table></div>
<p>As you can see, this approach leads to lot of code duplication if you count the number of <code>find</code> calls for each action per model. The <code>rescue_from</code> method is exactly the solution we are looking for. Instead of catching the exception at action-level, we instruct the controller to rescue all the <code>ActiveRecord::RecordNotFound</code> errors and forward the exception to the proper handler.</p>
<div class="codecolorer-container text default code-ruby" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">class ApplicationController &lt; ActionController::Base<br />
&nbsp; rescue_from ActiveRecord::RecordNotFound, :with =&gt; :render_404<br />
end<br />
<br />
class PostsController &lt; ApplicationController<br />
&nbsp; def show<br />
&nbsp; &nbsp; @post = Post.find(params[:id])<br />
&nbsp; end<br />
<br />
&nbsp; def edit<br />
&nbsp; &nbsp; @post = Post.find(params[:id])<br />
&nbsp; end<br />
<br />
&nbsp; def destroy<br />
&nbsp; &nbsp; @post = Post.find(params[:id])<br />
&nbsp; &nbsp; @post.destroy<br />
&nbsp; end<br />
<br />
end<br />
<br />
class UserController &lt; ApplicationController<br />
&nbsp; def show<br />
&nbsp; &nbsp; @user = User.find(params[:id])<br />
&nbsp; end<br />
<br />
&nbsp; # ...<br />
end</div></td></tr></tbody></table></div>
<p>The <code>rescue_from</code> method also accepts a <code>block</code> or a <code>Proc</code>. And if you need, you can also <a title="Re-raise a Ruby exception in a Rails rescue_from statement  –  Simone Carletti's Blog" href="http://www.simonecarletti.com/blog/2009/11/re-raise-a-ruby-exception-in-a-rails-rescue_from-statement/">selectively rescue exceptions according to the error message</a> or other properties.</p>
<h2><code>rescue_from</code> and Ruby</h2>
<p>The <code>rescue_from</code> was born as a Rails feature but because it&#8217;s packaged in the <code>ActiveSupport::Rescuable</code> module, you can easily reuse it elsewhere in your code to take advantage of the same clean and concise exception handling mechanism.</p>
<p>All you have to do is to require <code>ActiveSupport</code> library and include the <code>ActiveSupport::Rescuable</code> module in your class. If you are in a Rails project, <code>ActiveSupport</code> is already loaded. Then, add a <code>rescue</code> block and use the <code>rescue_with_handler</code> method to filter any error raised by the application.</p>
<div class="codecolorer-container text default code-ruby" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">class MyClass<br />
&nbsp; include ActiveSupport::Rescuable<br />
<br />
&nbsp; def method<br />
&nbsp; &nbsp; # ...<br />
&nbsp; rescue Exception =&gt; exception<br />
&nbsp; &nbsp; rescue_with_handler(exception) || raise<br />
&nbsp; end<br />
end</div></td></tr></tbody></table></div>
<p>The following is a simplified example extracted from <a title="RoboDomain" href="http://www.robodomain.com/">RoboDomain</a>. The <code>Queue::Jobs::Base</code> is the base class for all <code>DelayedJob</code> jobs. Each child class implements the <code>perform</code> method, as requested by <code>DelayedJob</code>. However, the base class provides an internal method called <code>execute</code> which wraps all executions and rescues from some known errors to prevent <code>DelayedJob</code> to re-schedule the failed task.</p>
<div class="codecolorer-container text default code-ruby" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">class Queue::Jobs::Base<br />
&nbsp; include ActiveSupport::Rescuable<br />
<br />
&nbsp; rescue_from ActiveRecord::RecordNotFound, :with =&gt; :known_error<br />
<br />
&nbsp; protected<br />
<br />
&nbsp; &nbsp; def execute(&amp;block)<br />
&nbsp; &nbsp; &nbsp; yield<br />
&nbsp; &nbsp; rescue Exception =&gt; exception<br />
&nbsp; &nbsp; &nbsp; rescue_with_handler(exception) || raise<br />
&nbsp; &nbsp; end<br />
<br />
&nbsp; &nbsp; def known_error(exception)<br />
&nbsp; &nbsp; &nbsp; @error = exception<br />
&nbsp; &nbsp; &nbsp; Rails.logger.error &quot;[JOBS] Exception #{exception.class}: #{exception.message}&quot;<br />
&nbsp; &nbsp; end<br />
<br />
end<br />
<br />
class Queue::Jobs::FetchWhois &lt; Queue::Jobs::Base<br />
<br />
&nbsp; rescue_from Hostname::NotLikeDomain, :with =&gt; :known_error<br />
&nbsp; # ActiveRecord::RecordNotFound already defined in parent class<br />
<br />
&nbsp; def initialize(hostname_id)<br />
&nbsp; &nbsp; @hostname_id = hostname_id<br />
&nbsp; end<br />
<br />
&nbsp; def perform<br />
&nbsp; &nbsp; execute do<br />
&nbsp; &nbsp; &nbsp; hostname = Hostname.find(@hostname_id)<br />
&nbsp; &nbsp; end<br />
&nbsp; end<br />
<br />
end</div></td></tr></tbody></table></div>
<p>As you can see, using the <code>ActiveSupport::Rescuable</code> module I don&#8217;t need to clutter my code with multiple <code>begin</code>/<code>rescue</code>/<code>raise</code> statements.</p>
<h2>A word of warning</h2>
<p>Like any reusable pattern, <code>ActiveSupport::Rescuable</code> is not the ultimate and definitive solution for any piece of code where you need to rescue from an exception. Use it if you actually need it, don&#8217;t try to force your code to fit this implementation.</p>
<p>Related posts<ol>
<li><a href='http://www.simonecarletti.com/blog/2009/11/re-raise-a-ruby-exception-in-a-rails-rescue_from-statement/' rel='bookmark' title='Re-raise a Ruby exception in a Rails rescue_from statement'>Re-raise a Ruby exception in a Rails rescue_from statement</a></li>
<li><a href='http://www.simonecarletti.com/blog/2010/04/inside-ruby-on-rails-serializing-ruby-objects-with-json/' rel='bookmark' title='Understanding Ruby and Rails: Serializing Ruby objects with JSON'>Understanding Ruby and Rails: Serializing Ruby objects with JSON</a></li>
<li><a href='http://www.simonecarletti.com/blog/2011/04/understanding-ruby-and-rails-lazy-load-hooks/' rel='bookmark' title='Understanding Ruby and Rails: Lazy load hooks'>Understanding Ruby and Rails: Lazy load hooks</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.simonecarletti.com/blog/2009/12/inside-ruby-on-rails-rescuable-and-rescue_from/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Re-raise a Ruby exception in a Rails rescue_from statement</title>
		<link>http://www.simonecarletti.com/blog/2009/11/re-raise-a-ruby-exception-in-a-rails-rescue_from-statement/</link>
		<comments>http://www.simonecarletti.com/blog/2009/11/re-raise-a-ruby-exception-in-a-rails-rescue_from-statement/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 19:58:02 +0000</pubDate>
		<dc:creator>Simone Carletti</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[exceptions]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.simonecarletti.com/blog/?p=704</guid>
		<description><![CDATA[How to rescue an exceptions according to exception message with Rails rescue_from statement.]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s say you are using <a title="Ryan's Scraps: What's New in Edge Rails: Better Exception Handling" href="http://ryandaigle.com/articles/2007/9/24/what-s-new-in-edge-rails-better-exception-handling">rescue_from</a> in your Rails application to rescue some type of exceptions that are thrown in your application. For example, you want to rescue a <code>ActiveRecord::StatementInvalid</code> but not every <code>ActiveRecord::StatementInvalid</code>: just those <code>ActiveRecord::StatementInvalid</code> exceptions where the exception message matches a defined pattern.</p>
<p>In this specific case, the following code won&#8217;t work.<span id="more-704"></span></p>
<div class="codecolorer-container text default code-ruby" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">class ApplicationController &lt; ActionController::Base &nbsp; &nbsp; &nbsp;<br />
<br />
&nbsp; # ... &nbsp; &nbsp; &nbsp;<br />
<br />
&nbsp; rescue_from ActiveRecord::StatementInvalid, :with =&gt; :rescue_invalid_encoding<br />
<br />
&nbsp; protected<br />
<br />
&nbsp; &nbsp; def rescue_invalid_encoding<br />
&nbsp; &nbsp; &nbsp; # ...<br />
&nbsp; &nbsp; end<br />
<br />
end</div></td></tr></tbody></table></div>
<p>This is because a <code>ActiveRecord::StatementInvalid</code> is a generic error class and the <code>rescue_from</code> statement will catch any <code>ActiveRecord::StatementInvalid</code> indistinctly. But you don&#8217;t want this, so you&#8217;ll decide to go ahead and use the old-fashioned if school to filter the exception message.</p>
<p>Only exceptions matching given message pattern should be catched. Any other exception should be released (or to use a technical jargon, <em>rethrown</em>).</p>
<div class="codecolorer-container text default code-ruby" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">class ApplicationController &lt; ActionController::Base<br />
<br />
&nbsp; # ...<br />
<br />
&nbsp; rescue_from ActiveRecord::StatementInvalid do |exception|<br />
&nbsp; &nbsp; if exception.message =~ /invalid byte sequence for encoding/<br />
&nbsp; &nbsp; &nbsp; rescue_invalid_encoding(exception)<br />
&nbsp; &nbsp; else<br />
&nbsp; &nbsp; &nbsp; raise<br />
&nbsp; &nbsp; end<br />
&nbsp; end<br />
<br />
&nbsp; protected<br />
<br />
&nbsp; &nbsp; def rescue_invalid_encoding(exception)<br />
&nbsp; &nbsp; &nbsp; head :bad_request<br />
&nbsp; &nbsp; end<br />
<br />
end</div></td></tr></tbody></table></div>
<p>The way you rethrow an exception in Ruby is calling <code>raise</code> without passing any exception class or message. Ruby will dutifully re-raise the more recent exception.</p>
<p>Unfortunately, the <code>else</code> statement won&#8217;t as expected. The <code>exception</code> is correctly rethrown but it isn&#8217;t catched by the standard Rails rescue mechanism and the standard exception page is not rendered. Also, the exception is completely invisible to any exception logging platform that relies on rescue_action_in_public such as <a title="Hoptoad" href="http://www.hoptoadapp.com/">Hoptoad</a> or <a title="Exceptional | Exception tracking and management for Ruby on Rails applications" href="http://getexceptional.com/">Exceptional</a>.</p>
<p>The explanation is simple. To prevent an infinite loop, Rails has a special Failsafe mechanism. When an Exception occurs in the Exception rescue execution, Rails immediately breaks the execution and enter in Failsafe mode.</p>
<p>From the Rails log</p>
<div class="codecolorer-container text default brush: text;" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Processing ApplicationController#index (for 127.0.0.1 at 2009-11-03 23:30:19) [GET]<br />
&nbsp; Parameters: {&quot;action&quot;=&gt;&quot;index&quot;, &quot;controller&quot;=&gt;&quot;welcome&quot;}<br />
/! FAILSAFE /! &nbsp;Wed Nov 03 23:30:19 +0100 2009<br />
&nbsp; Status: 500 Internal Server Error<br />
&nbsp; ActiveRecord::StatementInvalid</div></td></tr></tbody></table></div>
<p>In order to pass invoke the standard rescue mechanism you need to manually call the <code>rescue_action_without_handler(exception)</code> method.</p>
<div class="codecolorer-container text default code-ruby" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">class ApplicationController &lt; ActionController::Base<br />
<br />
&nbsp; # ...<br />
<br />
&nbsp; rescue_from ActiveRecord::StatementInvalid do |exception|<br />
&nbsp; &nbsp; if exception.message =~ /invalid encoding/<br />
&nbsp; &nbsp; &nbsp; rescue_invalid_encoding(exception)<br />
&nbsp; &nbsp; else<br />
&nbsp; &nbsp; &nbsp; rescue_action_without_handler(exception)<br />
&nbsp; &nbsp; end<br />
&nbsp; end<br />
<br />
&nbsp; protected<br />
<br />
&nbsp; &nbsp; def rescue_invalid_encoding(exception)<br />
&nbsp; &nbsp; &nbsp; head :bad_request<br />
&nbsp; &nbsp; end<br />
<br />
end</div></td></tr></tbody></table></div>
<p>A work of warning: This is a Rails internal API so it can change without additional notice in future versions so be sure to create a test suite to prevent problems when upgrading your Rails version.</p>
<p>Here&#8217;s an example of integrational test.</p>
<div class="codecolorer-container text default code-ruby" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">require 'test_helper'<br />
<br />
class RescuableTest &lt; ActionController::IntegrationTest<br />
<br />
&nbsp; fixtures :all<br />
<br />
&nbsp; test &quot;rescue from ActiveRecord::StatementInvalid&quot; do<br />
&nbsp; &nbsp; MainController.any_instance.expects(:set_locale).raises(ActiveRecord::StatementInvalid, 'PGError: ERROR: invalid byte sequence for encoding &quot;UTF8&quot;: 0xed706')<br />
<br />
&nbsp; &nbsp; get &quot;/&quot;<br />
&nbsp; &nbsp; assert_response 400<br />
&nbsp; end<br />
<br />
&nbsp; test &quot;rescue from ActiveRecord::StatementInvalid with re-raise&quot; do<br />
&nbsp; &nbsp; MainController.any_instance.expects(:set_locale).raises(ActiveRecord::StatementInvalid, 'Global error')<br />
<br />
&nbsp; &nbsp; get &quot;/&quot;<br />
&nbsp; &nbsp; assert_response 500<br />
&nbsp; &nbsp; # perhaps you might want to check here additional instance variables<br />
&nbsp; &nbsp; # or flash messages<br />
&nbsp; end<br />
<br />
end</div></td></tr></tbody></table></div>
<p>Related posts<ol>
<li><a href='http://www.simonecarletti.com/blog/2009/12/inside-ruby-on-rails-rescuable-and-rescue_from/' rel='bookmark' title='Understanding Ruby and Rails: Rescuable and rescue_from'>Understanding Ruby and Rails: Rescuable and rescue_from</a></li>
<li><a href='http://www.simonecarletti.com/blog/2009/09/inside-ruby-on-rails-extract_options-from-arrays/' rel='bookmark' title='Understanding Ruby and Rails: extract_options! from Arrays'>Understanding Ruby and Rails: extract_options! from Arrays</a></li>
<li><a href='http://www.simonecarletti.com/blog/2011/04/understanding-ruby-and-rails-lazy-load-hooks/' rel='bookmark' title='Understanding Ruby and Rails: Lazy load hooks'>Understanding Ruby and Rails: Lazy load hooks</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.simonecarletti.com/blog/2009/11/re-raise-a-ruby-exception-in-a-rails-rescue_from-statement/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

