Include template name with line numbers in render errors.

This commit is contained in:
Dylan Thacker-Smith
2015-06-04 13:44:01 -04:00
parent c82e04f4e6
commit ad3748af21
4 changed files with 45 additions and 16 deletions
+2 -1
View File
@@ -13,7 +13,7 @@ module Liquid
# context['bob'] #=> nil class Context # context['bob'] #=> nil class Context
class Context class Context
attr_reader :scopes, :errors, :registers, :environments, :resource_limits attr_reader :scopes, :errors, :registers, :environments, :resource_limits
attr_accessor :exception_handler attr_accessor :exception_handler, :template_name
def initialize(environments = {}, outer_scope = {}, registers = {}, rethrow_errors = false, resource_limits = nil) def initialize(environments = {}, outer_scope = {}, registers = {}, rethrow_errors = false, resource_limits = nil)
@environments = [environments].flatten @environments = [environments].flatten
@@ -64,6 +64,7 @@ module Liquid
def handle_error(e, token = nil) def handle_error(e, token = nil)
if e.is_a?(Liquid::Error) if e.is_a?(Liquid::Error)
e.template_name = template_name
e.set_line_number_from_token(token) e.set_line_number_from_token(token)
end end
+4 -1
View File
@@ -1,6 +1,7 @@
module Liquid module Liquid
class Error < ::StandardError class Error < ::StandardError
attr_accessor :line_number attr_accessor :line_number
attr_accessor :template_name
attr_accessor :markup_context attr_accessor :markup_context
def to_s(with_prefix = true) def to_s(with_prefix = true)
@@ -41,7 +42,9 @@ module Liquid
end end
if line_number if line_number
str << " (line #{line_number})" str << " ("
str << template_name << " " if template_name
str << "line " << line_number.to_s << ")"
end end
str << ": " str << ": "
+19 -14
View File
@@ -41,9 +41,9 @@ module Liquid
end end
def render(context) def render(context)
partial = load_cached_partial(context)
template_name = context.evaluate(@template_name_expr) template_name = context.evaluate(@template_name_expr)
partial = load_cached_partial(template_name, context)
context_variable_name = template_name.split('/'.freeze).last context_variable_name = template_name.split('/'.freeze).last
variable = if @variable_name_expr variable = if @variable_name_expr
@@ -52,28 +52,33 @@ module Liquid
context.find_variable(template_name) context.find_variable(template_name)
end end
context.stack do old_template_name = context.template_name
@attributes.each do |key, value| begin
context[key] = context.evaluate(value) context.template_name = template_name
end context.stack do
@attributes.each do |key, value|
context[key] = context.evaluate(value)
end
if variable.is_a?(Array) if variable.is_a?(Array)
variable.collect do |var| variable.collect do |var|
context[context_variable_name] = var context[context_variable_name] = var
partial.render(context)
end
else
context[context_variable_name] = variable
partial.render(context) partial.render(context)
end end
else
context[context_variable_name] = variable
partial.render(context)
end end
ensure
context.template_name = old_template_name
end end
end end
private private
def load_cached_partial(context) def load_cached_partial(template_name, context)
cached_partials = context.registers[:cached_partials] || {} cached_partials = context.registers[:cached_partials] || {}
template_name = context.evaluate(@template_name_expr)
if cached = cached_partials[template_name] if cached = cached_partials[template_name]
return cached return cached
+20
View File
@@ -203,4 +203,24 @@ class ErrorHandlingTest < Minitest::Test
assert_equal 'This is a runtime error: Liquid error (line 1): internal', output assert_equal 'This is a runtime error: Liquid error (line 1): internal', output
assert_equal [InternalError], template.errors.map(&:class) assert_equal [InternalError], template.errors.map(&:class)
end end
class TestFileSystem
def read_template_file(template_path)
"{{ errors.argument_error }}"
end
end
def test_included_template_name_with_line_numbers
old_file_system = Liquid::Template.file_system
begin
Liquid::Template.file_system = TestFileSystem.new
template = Liquid::Template.parse("Argument error:\n{% include 'product' %}", line_numbers: true)
page = template.render('errors' => ErrorDrop.new)
ensure
Liquid::Template.file_system = old_file_system
end
assert_equal "Argument error:\nLiquid error (product line 1): argument error", page
assert_equal "product", template.errors.first.template_name
end
end end