diff options
author | Rafael França <rafaelmfranca@gmail.com> | 2019-03-28 14:53:22 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-28 14:53:22 -0400 |
commit | e3f5f1c936869b81b01835adc9c683e058edfeaf (patch) | |
tree | 7cc31fadaa654951237faf843015be6b070ae382 /actionview | |
parent | 78ace9cd080e626feb89ffb9e4142f0b672a53b3 (diff) | |
parent | 07804d4759726da04020834502d37a8f4ac97a8f (diff) | |
download | rails-e3f5f1c936869b81b01835adc9c683e058edfeaf.tar.gz rails-e3f5f1c936869b81b01835adc9c683e058edfeaf.tar.bz2 rails-e3f5f1c936869b81b01835adc9c683e058edfeaf.zip |
Merge pull request #35308 from erose/better-error-reporting-for-syntax-errors-in-templates
Display a more helpful error message when an ERB template has a Ruby syntax error.
Diffstat (limited to 'actionview')
-rw-r--r-- | actionview/lib/action_view/template.rb | 10 | ||||
-rw-r--r-- | actionview/lib/action_view/template/error.rb | 20 | ||||
-rw-r--r-- | actionview/test/fixtures/test/syntax_error.html.erb | 4 | ||||
-rw-r--r-- | actionview/test/template/render_test.rb | 6 |
4 files changed, 39 insertions, 1 deletions
diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb index 6e3af1536a..7bc5e86edb 100644 --- a/actionview/lib/action_view/template.rb +++ b/actionview/lib/action_view/template.rb @@ -331,6 +331,7 @@ module ActionView # Make sure that the resulting String to be eval'd is in the # encoding of the code + original_source = source source = +<<-end_src def #{method_name}(local_assigns, output_buffer) @virtual_path = #{@virtual_path.inspect};#{locals_code};#{code} @@ -351,7 +352,14 @@ module ActionView raise WrongEncodingError.new(source, Encoding.default_internal) end - mod.module_eval(source, identifier, 0) + begin + mod.module_eval(source, identifier, 0) + rescue SyntaxError + # Account for when code in the template is not syntactically valid; e.g. if we're using + # ERB and the user writes <%= foo( %>, attempting to call a helper `foo` and interpolate + # the result into the template, but missing an end parenthesis. + raise SyntaxErrorInTemplate.new(self, original_source) + end end def handle_render_error(view, e) diff --git a/actionview/lib/action_view/template/error.rb b/actionview/lib/action_view/template/error.rb index 4e3c02e05e..ff01e4cd83 100644 --- a/actionview/lib/action_view/template/error.rb +++ b/actionview/lib/action_view/template/error.rb @@ -138,4 +138,24 @@ module ActionView end TemplateError = Template::Error + + class SyntaxErrorInTemplate < TemplateError #:nodoc + def initialize(template, offending_code_string) + @offending_code_string = offending_code_string + super(template) + end + + def message + <<~MESSAGE + Encountered a syntax error while rendering template: check #{@offending_code_string} + MESSAGE + end + + def annoted_source_code + @offending_code_string.split("\n").map.with_index(1) { |line, index| + indentation = " " * 4 + "#{index}:#{indentation}#{line}" + } + end + end end diff --git a/actionview/test/fixtures/test/syntax_error.html.erb b/actionview/test/fixtures/test/syntax_error.html.erb new file mode 100644 index 0000000000..4004a2b187 --- /dev/null +++ b/actionview/test/fixtures/test/syntax_error.html.erb @@ -0,0 +1,4 @@ +<%= foo( + 1, + 2, +%> diff --git a/actionview/test/template/render_test.rb b/actionview/test/template/render_test.rb index f0fed601f8..dbce370350 100644 --- a/actionview/test/template/render_test.rb +++ b/actionview/test/template/render_test.rb @@ -259,6 +259,12 @@ module RenderTestCases "and is followed by any combination of letters, numbers and underscores.", e.message end + def test_render_template_with_syntax_error + e = assert_raises(ActionView::Template::Error) { @view.render(template: "test/syntax_error") } + assert_match %r!syntax!, e.message + assert_equal "1: <%= foo(", e.annoted_source_code[0].strip + end + def test_render_partial_with_errors e = assert_raises(ActionView::Template::Error) { @view.render(partial: "test/raise") } assert_match %r!method.*doesnt_exist!, e.message |