diff options
author | José Valim <jose.valim@gmail.com> | 2011-05-01 13:39:15 +0200 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2011-05-01 13:40:14 +0200 |
commit | 46611a995d91abf7bb2a64c62af13b6449c75b07 (patch) | |
tree | 1f2600e1c02142135ec8ea0f5309bb232c0997bf /actionpack | |
parent | 6960a230fa2c2b7cf59266fc903ce0c11e887a9f (diff) | |
download | rails-46611a995d91abf7bb2a64c62af13b6449c75b07.tar.gz rails-46611a995d91abf7bb2a64c62af13b6449c75b07.tar.bz2 rails-46611a995d91abf7bb2a64c62af13b6449c75b07.zip |
log errors when an exception happens when streaming.
Diffstat (limited to 'actionpack')
4 files changed, 37 insertions, 3 deletions
diff --git a/actionpack/lib/action_view/context.rb b/actionpack/lib/action_view/context.rb index 01be294284..d501a6eaf9 100644 --- a/actionpack/lib/action_view/context.rb +++ b/actionpack/lib/action_view/context.rb @@ -15,6 +15,8 @@ module ActionView include CompiledTemplates attr_accessor :output_buffer, :view_flow + # TODO Provide an easy method that initializes all variables? + # Returns the contents that are yielded to a layout, given a name or a block. # # You can think of a layout as a method that is called with a block. If the user calls diff --git a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb index d60b42a284..d987bc122a 100644 --- a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb +++ b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb @@ -60,11 +60,26 @@ module ActionView def each(&block) begin @start.call(block) - rescue + rescue Exception => exception + log_error(exception) block.call ActionView::Base.streaming_completion_on_exception end self end + + private + + # This is the same logging logic as in ShowExceptions middleware. + # TODO Once "exceptron" is in, refactor this piece to simply re-use exceptron. + def log_error(exception) #:nodoc: + logger = ActionController::Base.logger + return unless logger + + message = "\n#{exception.class} (#{exception.message}):\n" + message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code) + message << " " << exception.backtrace.join("\n ") + logger.fatal("#{message}\n\n") + end end # For streaming, instead of rendering a given a template, we return a Body diff --git a/actionpack/test/controller/new_base/render_streaming_test.rb b/actionpack/test/controller/new_base/render_streaming_test.rb index fed8d40b47..48cf0ab9cb 100644 --- a/actionpack/test/controller/new_base/render_streaming_test.rb +++ b/actionpack/test/controller/new_base/render_streaming_test.rb @@ -83,6 +83,19 @@ module RenderStreaming assert_streaming! end + test "rendering with template exception logs the exception" do + io = StringIO.new + _old, ActionController::Base.logger = ActionController::Base.logger, Logger.new(io) + + begin + get "/render_streaming/basic/template_exception" + io.rewind + assert_match "(undefined method `invalid!' for nil:NilClass)", io.read + ensure + ActionController::Base.logger = _old + end + end + test "do not stream on HTTP/1.0" do get "/render_streaming/basic/hello_world", nil, "HTTP_VERSION" => "HTTP/1.0" assert_body "Hello world, I'm here!" diff --git a/actionpack/test/template/streaming_render_test.rb b/actionpack/test/template/streaming_render_test.rb index 4d69081570..b2df8efee3 100644 --- a/actionpack/test/template/streaming_render_test.rb +++ b/actionpack/test/template/streaming_render_test.rb @@ -13,8 +13,12 @@ class FiberedTest < ActiveSupport::TestCase @controller_view = TestController.new.view_context end + def render_body(options) + @view.view_renderer.render_body(@view, options) + end + def buffered_render(options) - body = @view.render_body(options) + body = render_body(options) string = "" body.each do |piece| string << piece @@ -24,7 +28,7 @@ class FiberedTest < ActiveSupport::TestCase def test_streaming_works content = [] - body = @view.render_body(:template => "test/hello_world.erb", :layout => "layouts/yield") + body = render_body(:template => "test/hello_world.erb", :layout => "layouts/yield") body.each do |piece| content << piece |