diff --git a/lib/liquid/errors.rb b/lib/liquid/errors.rb index feb4262..1fa71bb 100644 --- a/lib/liquid/errors.rb +++ b/lib/liquid/errors.rb @@ -49,6 +49,10 @@ module Liquid end end + class FilterError < Error + attr_accessor :original_exception + end + ArgumentError = Class.new(Error) ContextError = Class.new(Error) FileSystemError = Class.new(Error) diff --git a/lib/liquid/strainer.rb b/lib/liquid/strainer.rb index c9bd1eb..ac6ebd3 100644 --- a/lib/liquid/strainer.rb +++ b/lib/liquid/strainer.rb @@ -47,12 +47,20 @@ module Liquid def invoke(method, *args) if self.class.invokable?(method) - send(method, *args) + begin + send(method, *args) + rescue ::ArgumentError => e + raise Liquid::ArgumentError.new(e.message) + rescue Liquid::Error + raise + rescue ::StandardError => exception + error = Liquid::FilterError.new(exception.message) + error.original_exception = exception + raise error + end else args.first end - rescue ::ArgumentError => e - raise Liquid::ArgumentError.new(e.message) end end end diff --git a/test/integration/filter_test.rb b/test/integration/filter_test.rb index e346444..3d2aea9 100644 --- a/test/integration/filter_test.rb +++ b/test/integration/filter_test.rb @@ -22,6 +22,12 @@ module SubstituteFilter end end +module ErrorFilter + def standard_error(input) + raise ::StandardError, 'standard error' + end +end + class FiltersTest < Minitest::Test include Liquid @@ -158,7 +164,14 @@ class FiltersInTemplate < Minitest::Test assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, CanadianMoneyFilter) assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, [CanadianMoneyFilter]) end -end # FiltersTest + + def test_filter_error + context = Context.new + context.add_filters(ErrorFilter) + assert_equal "Liquid error: standard error", Template.parse("{{'var' | standard_error}}").render(context) + assert_equal [Liquid::FilterError], context.errors.map(&:class) + end +end class TestObject attr_accessor :a diff --git a/test/integration/template_test.rb b/test/integration/template_test.rb index a44f8c1..d9062d1 100644 --- a/test/integration/template_test.rb +++ b/test/integration/template_test.rb @@ -201,14 +201,16 @@ class TemplateTest < Minitest::Test def test_exception_handler_doesnt_reraise_if_it_returns_false exception = nil Template.parse("{{ 1 | divided_by: 0 }}").render({}, exception_handler: ->(e) { exception = e; false }) - assert exception.is_a?(ZeroDivisionError) + assert exception.is_a?(Liquid::FilterError) + assert exception.original_exception.is_a?(ZeroDivisionError) end def test_exception_handler_does_reraise_if_it_returns_true exception = nil - assert_raises(ZeroDivisionError) do + assert_raises(Liquid::FilterError) do Template.parse("{{ 1 | divided_by: 0 }}").render({}, exception_handler: ->(e) { exception = e; true }) end - assert exception.is_a?(ZeroDivisionError) + assert exception.is_a?(Liquid::FilterError) + assert exception.original_exception.is_a?(ZeroDivisionError) end end