未验证 提交 e3f5f1c9 编写于 作者: R Rafael França 提交者: GitHub

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.
......@@ -331,6 +331,7 @@ def compile(mod)
# 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 @@ def #{method_name}(local_assigns, output_buffer)
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)
......
......@@ -138,4 +138,24 @@ def formatted_code_for(source_code, line_counter, indent, output)
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
......@@ -259,6 +259,12 @@ def test_render_partial_with_hyphen_and_invalid_option_as
"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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册