From 203032dd76651200a70319e6b2fb2bff2216e368 Mon Sep 17 00:00:00 2001 From: Alex Ghiculescu Date: Tue, 17 May 2022 10:22:08 -0500 Subject: [PATCH] Fix incorrect line number if a `helper_method` errors Currently if you use `helper_method` to define a method, and inside that method you get an error, the backtrace is off by one line. This PR fixes that so that the backtrace now points to the line where you called `helper_method`. --- actionpack/lib/abstract_controller/helpers.rb | 11 +++++++---- actionpack/test/controller/helper_test.rb | 13 +++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/actionpack/lib/abstract_controller/helpers.rb b/actionpack/lib/abstract_controller/helpers.rb index bb69e7997e6..45393eed6a9 100644 --- a/actionpack/lib/abstract_controller/helpers.rb +++ b/actionpack/lib/abstract_controller/helpers.rb @@ -84,10 +84,13 @@ module AbstractController file, line = location.path, location.lineno methods.each do |method| - _helpers_for_modification.class_eval <<~ruby_eval, file, line - def #{method}(*args, &block) # def current_user(*args, &block) - controller.send(:'#{method}', *args, &block) # controller.send(:'current_user', *args, &block) - end # end + # def current_user(*args, &block) + # controller.send(:'current_user', *args, &block) + # end + _helpers_for_modification.class_eval <<~ruby_eval.lines.map(&:strip).join(";"), file, line + def #{method}(*args, &block) + controller.send(:'#{method}', *args, &block) + end ruby2_keywords(:'#{method}') ruby_eval end diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb index 29f77b9ff47..01bc06b158e 100644 --- a/actionpack/test/controller/helper_test.rb +++ b/actionpack/test/controller/helper_test.rb @@ -98,6 +98,9 @@ class HelperTest < ActiveSupport::TestCase def delegate_method() end def delegate_method_arg(arg); arg; end def delegate_method_kwarg(hi:); hi; end + def method_that_raises + raise "an error occurred" + end end def setup @@ -145,6 +148,16 @@ class HelperTest < ActiveSupport::TestCase assert_equal(:there, @controller_class.new.helpers.delegate_method_kwarg(hi: :there)) end + def test_helper_method_with_error_has_correct_backgrace + @controller_class.helper_method :method_that_raises + expected_backtrace_pattern = "#{__FILE__}:#{__LINE__ - 1}" + + error = assert_raises(RuntimeError) do + @controller_class.new.helpers.method_that_raises + end + assert_not_nil error.backtrace.find { |line| line.include?(expected_backtrace_pattern) } + end + def test_helper_attr assert_nothing_raised { @controller_class.helper_attr :delegate_attr } assert_includes master_helper_methods, :delegate_attr