Project

General

Profile

« Previous | Next » 

Revision 3a766513

Added by Marek Hulán over 7 years ago

Fixes #18345 - Improve templates error handling

View differences:

app/controllers/templates_controller.rb
render :text => unattended_render(template)
rescue => error
Foreman::Logging.exception("Error rendering the #{template.name} template", error)
render :text => _("There was an error rendering the %{name} template: %{error}") % {:name => template.name, :error => error.message},
:status => :internal_server_error
if error.is_a?(Foreman::Renderer::RenderingError)
text = error.message
else
text = _("There was an error rendering the %{name} template: %{error}") % {:name => template.name, :error => error.message}
end
render :text => text, :status => :internal_server_error
end
def set_locked(locked)
lib/foreman/renderer.rb
module Foreman
module Renderer
class RenderingError < Foreman::Exception; end
class SyntaxError < RenderingError; end
include ::Foreman::ForemanUrlRenderer
ALLOWED_GENERIC_HELPERS ||= [ :foreman_url, :snippet, :snippets, :snippet_if_exists, :indent, :foreman_server_fqdn,
......
def render_safe(template, allowed_methods = [], allowed_vars = {}, scope_variables = {})
if Setting[:safemode_render]
box = Safemode::Box.new self, allowed_methods
box.eval(ERB.new(template, nil, '-').src, allowed_vars.merge(scope_variables))
box = Safemode::Box.new self, allowed_methods, template_name
erb = ERB.new(template, nil, '-')
box.eval(erb.src, allowed_vars.merge(scope_variables))
else
# we need to keep scope variables and reset them after rendering otherwise they would remain
# after snippets are rendered in parent template scope
......
scope_variables.each { |k,v| kept_variables[k] = instance_variable_get("@#{k}") }
allowed_vars.merge(scope_variables).each { |k,v| instance_variable_set "@#{k}", v }
result = ERB.new(template, nil, '-').result(binding)
erb = ERB.new(template, nil, '-')
# erb allows to set location since Ruby 2.2
erb.location = template_name, 0 if erb.respond_to?(:location=)
result = erb.result(binding)
scope_variables.each { |k,v| instance_variable_set "@#{k}", kept_variables[k] }
result
end
rescue ::Racc::ParseError, ::SyntaxError => e
# Racc::ParseError is raised in safe mode, SyntaxError in unsafe mode
new_e = Foreman::Renderer::SyntaxError.new(N_("Syntax error occurred while parsing the template %{template_name}, make sure you have all ERB tags properly closed and the Ruby syntax is valid. The Ruby error: %{message}"), :template_name => template_name, :message => e.message)
new_e.set_backtrace(e.backtrace)
raise new_e
end
def foreman_server_fqdn
......
begin
return unattended_render(template, nil, options[:variables] || {})
rescue => exc
raise "The snippet '#{name}' threw an error: #{exc}"
if exc.is_a?(::Foreman::Exception)
raise exc
else
e = ::Foreman::Exception.new(N_("The snippet '%{name}' threw an error: %{exc}"), { :name => name, :exc => exc })
e.set_backtrace exc.backtrace
raise e
end
end
else
if options[:silent]
test/controllers/provisioning_templates_controller_test.rb
assert_equal '2', @response.body
post :preview, { :template => '<%= 1+ -%>', :id => template }, set_session_user
assert_includes @response.body, 'There was an error'
assert_includes @response.body, 'parse error on value'
end
context 'templates combinations' do
test/controllers/ptables_controller_test.rb
assert_equal '2', @response.body
post :preview, { :template => '<%= 1+ -%>', :id => template }, set_session_user
assert_includes @response.body, 'There was an error'
assert_includes @response.body, 'parse error on value'
end
end
test/unit/foreman/renderer_test.rb
end
end
test "#{renderer_name} should raise renderer syntax error on syntax error" do
send "setup_#{renderer_name}"
template = <<EOS
line 1: ok
line 2: ok
line 3: <%= 1 + %>
line 4: ok
EOS
@renderer.instance_variable_set '@template_name', 'my_template'
exception = assert_raises Foreman::Renderer::SyntaxError do
@renderer.render_safe(template, [], {})
end
if renderer_name == :normal_renderer
assert_include exception.message, 'my_template:3' if ERB.method_defined?(:location=)
assert_include exception.message, "syntax error, unexpected ')'"
else
assert_include exception.message, 'parse error on value ")"'
end
end
test "#{renderer_name} should evaluate template variables" do
send "setup_#{renderer_name}"
tmpl = @renderer.render_safe('<%= @foo %>', [], { :foo => 'bar' })

Also available in: Unified diff