From 869dbc7ebf6cb68f0d32baf7e86f2a4fa2f14f3e Mon Sep 17 00:00:00 2001 From: Dylan Thacker-Smith Date: Mon, 12 Dec 2016 10:29:09 -0500 Subject: [PATCH] feature: Allow a default exception renderer to be specified (#837) This could be used to preserve the old default of rendering non-Liquid::Error messages or for providing default behaviour like error reporting which could be missed if the exception renderer needed to be specified on each render. --- lib/liquid/context.rb | 5 ++--- lib/liquid/template.rb | 5 +++++ test/integration/error_handling_test.rb | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/liquid/context.rb b/lib/liquid/context.rb index 2b7544b..6ba2353 100644 --- a/lib/liquid/context.rb +++ b/lib/liquid/context.rb @@ -27,6 +27,7 @@ module Liquid @this_stack_used = false + self.exception_renderer = Template.default_exception_renderer if rethrow_errors self.exception_renderer = ->(e) { raise } end @@ -78,9 +79,7 @@ module Liquid e.template_name ||= template_name e.line_number ||= line_number errors.push(e) - - e = exception_renderer.call(e) if exception_renderer - e.to_s + exception_renderer.call(e).to_s end def invoke(method, *args) diff --git a/lib/liquid/template.rb b/lib/liquid/template.rb index ebd8fc0..31a67e4 100644 --- a/lib/liquid/template.rb +++ b/lib/liquid/template.rb @@ -69,6 +69,11 @@ module Liquid # :error raises an error when tainted output is used attr_writer :taint_mode + attr_accessor :default_exception_renderer + Template.default_exception_renderer = lambda do |exception| + exception + end + def file_system @@file_system end diff --git a/test/integration/error_handling_test.rb b/test/integration/error_handling_test.rb index 9d20be2..ba81861 100644 --- a/test/integration/error_handling_test.rb +++ b/test/integration/error_handling_test.rb @@ -211,6 +211,20 @@ class ErrorHandlingTest < Minitest::Test assert_equal [Liquid::InternalError], template.errors.map(&:class) end + def test_setting_default_exception_renderer + old_exception_renderer = Liquid::Template.default_exception_renderer + exceptions = [] + Liquid::Template.default_exception_renderer = ->(e) { exceptions << e; '' } + template = Liquid::Template.parse('This is a runtime error: {{ errors.argument_error }}') + + output = template.render({ 'errors' => ErrorDrop.new }) + + assert_equal 'This is a runtime error: ', output + assert_equal [Liquid::ArgumentError], template.errors.map(&:class) + ensure + Liquid::Template.default_exception_renderer = old_exception_renderer if old_exception_renderer + end + def test_exception_renderer_exposing_non_liquid_error template = Liquid::Template.parse('This is a runtime error: {{ errors.runtime_error }}', line_numbers: true) exceptions = []