From cd4864256125001326a223256426b1b554810d47 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Sun, 9 Oct 2022 14:51:26 -0700 Subject: [PATCH] Add tests that column information can be translated --- actionview/lib/action_view/template/error.rb | 2 ++ .../lib/action_view/template/handlers/erb.rb | 3 ++- .../test/fixtures/test/runtime_error.html.erb | 6 +++++ actionview/test/template/render_test.rb | 23 +++++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 actionview/test/fixtures/test/runtime_error.html.erb diff --git a/actionview/lib/action_view/template/error.rb b/actionview/lib/action_view/template/error.rb index 7a2f96ec9b..b7d522a801 100644 --- a/actionview/lib/action_view/template/error.rb +++ b/actionview/lib/action_view/template/error.rb @@ -157,6 +157,8 @@ class Error < ActionViewError # :nodoc: # Override to prevent #cause resetting during re-raise. attr_reader :cause + attr_reader :template + def initialize(template) super($!.message) @cause = $! diff --git a/actionview/lib/action_view/template/handlers/erb.rb b/actionview/lib/action_view/template/handlers/erb.rb index c0681e43fa..df121ccdda 100644 --- a/actionview/lib/action_view/template/handlers/erb.rb +++ b/actionview/lib/action_view/template/handlers/erb.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "strscan" +require "active_support/core_ext/string" module ActionView class Template @@ -39,7 +40,7 @@ def handles_encoding? # source location inside the template. def translate_location(spot, backtrace_location, source) # Tokenize the source line - tokens = ERB::Util.tokenize(source.lines[backtrace_location.lineno - 1]) + tokens = ::ERB::Util.tokenize(source.lines[backtrace_location.lineno - 1]) new_first_column = find_offset(spot[:snippet], tokens, spot[:first_column]) lineno_delta = spot[:first_lineno] - backtrace_location.lineno spot[:first_lineno] -= lineno_delta diff --git a/actionview/test/fixtures/test/runtime_error.html.erb b/actionview/test/fixtures/test/runtime_error.html.erb new file mode 100644 index 0000000000..f1151b1517 --- /dev/null +++ b/actionview/test/fixtures/test/runtime_error.html.erb @@ -0,0 +1,6 @@ +

Oh no!

+This template has a runtime error + + <%= method_that_does_not_exist %> + +Yikes! diff --git a/actionview/test/template/render_test.rb b/actionview/test/template/render_test.rb index f2dfb6070d..16be200bf0 100644 --- a/actionview/test/template/render_test.rb +++ b/actionview/test/template/render_test.rb @@ -210,6 +210,29 @@ def test_render_outside_path end end + def test_render_runtime_error + skip unless RubyVM.respond_to?(:keep_script_lines) + + # We need to enable this setting so that when we eval the template + # the compiled source is kept around. + setting = RubyVM.keep_script_lines + RubyVM.keep_script_lines = true + + ex = assert_raises(ActionView::Template::Error) { + @view.render(template: "test/runtime_error") + } + erb_btl = ex.backtrace_locations.first + + # Get the spot information from ErrorHighlight + spot = erb_btl.spot(ex.cause) + translated_spot = ex.template.translate_location(erb_btl, spot) + assert_equal 6, translated_spot[:first_column] + ensure + if RubyVM.respond_to?(:keep_script_lines) + RubyVM.keep_script_lines = setting + end + end + def test_render_partial assert_equal "only partial", @view.render(partial: "test/partial_only") end