From 7ddf05e945706443827f343bf09122faac1d09e0 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Tue, 8 Jun 2010 05:17:21 -0400 Subject: [PATCH] Exceptions from views should be rescued based on the original exception. If a handler for original exception is missing then apply ActiveView::TemplateError [#2034 state:resolved] --- activesupport/lib/active_support/rescuable.rb | 10 +++++- activesupport/test/rescuable_test.rb | 41 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletions(-) diff --git a/activesupport/lib/active_support/rescuable.rb b/activesupport/lib/active_support/rescuable.rb index cd6f92c..7e83df1 100644 --- a/activesupport/lib/active_support/rescuable.rb +++ b/activesupport/lib/active_support/rescuable.rb @@ -75,7 +75,15 @@ module ActiveSupport # Tries to rescue the exception by looking up and calling a registered handler. def rescue_with_handler(exception) - if handler = handler_for_rescue(exception) + if ((exception.class == ActionView::TemplateError) && (orig_exception = exception.original_exception) && + (orig_handler = handler_for_rescue(orig_exception))) + handler = orig_handler + exception = orig_exception + else + handler = handler_for_rescue(exception) + end + + if handler handler.arity != 0 ? handler.call(exception) : handler.call true # don't rely on the return value of the handler end diff --git a/activesupport/test/rescuable_test.rb b/activesupport/test/rescuable_test.rb index ff77e16..bbc97d0 100644 --- a/activesupport/test/rescuable_test.rb +++ b/activesupport/test/rescuable_test.rb @@ -67,3 +67,44 @@ class RescueableTest < Test::Unit::TestCase assert_equal 'dex', @stargate.result end end + +module ActionView + class ActionViewError < StandardError; end + + class TemplateError < ActionViewError + attr_accessor :original_exception + end +end + +class ViewExplosion + attr_accessor :result + + include ActiveSupport::Rescuable + + rescue_from ArgumentError do + @result = 'rescued_argument_error' + end + + def dispatch(method) + send(method) + rescue Exception => e + rescue_with_handler(e) + end + + def argument_error_in_view + e = ActionView::TemplateError.new + e.original_exception = ArgumentError.new('this is argument error') + raise e + end +end + +class ActionViewRescueableTest < Test::Unit::TestCase + def setup + @ve = ViewExplosion.new + end + + def test_rescue_from_argument_error_in_view + @ve.dispatch :argument_error_in_view + assert_equal 'rescued_argument_error', @ve.result + end +end -- 1.6.5.2