aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael França <rafaelmfranca@gmail.com>2019-03-28 14:53:22 -0400
committerGitHub <noreply@github.com>2019-03-28 14:53:22 -0400
commite3f5f1c936869b81b01835adc9c683e058edfeaf (patch)
tree7cc31fadaa654951237faf843015be6b070ae382
parent78ace9cd080e626feb89ffb9e4142f0b672a53b3 (diff)
parent07804d4759726da04020834502d37a8f4ac97a8f (diff)
downloadrails-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.
-rw-r--r--actionview/lib/action_view/template.rb10
-rw-r--r--actionview/lib/action_view/template/error.rb20
-rw-r--r--actionview/test/fixtures/test/syntax_error.html.erb4
-rw-r--r--actionview/test/template/render_test.rb6
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