From b398520c1406824efd12df6bb57996aa9781f876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 19 Apr 2011 12:25:01 +0200 Subject: Output a redirect to the 500 page if something happens when streaming. Currently, we output: "> --- actionpack/lib/action_view/base.rb | 6 ++++++ .../renderer/streaming_template_renderer.rb | 11 +++++----- .../controller/new_base/render_streaming_test.rb | 24 +++++++++++++++++++++- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 9e8a3c51a3..87501d5b88 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -137,6 +137,12 @@ module ActionView #:nodoc: cattr_accessor :field_error_proc @@field_error_proc = Proc.new{ |html_tag, instance| "
#{html_tag}
".html_safe } + # How to complete the streaming when an exception occurs. + # This is our best guess: first try to close the attribute, then the tag. + # Currently this is private API and may be changed at *any* time. + cattr_accessor :streaming_completion_on_exception + @@streaming_completion_on_exception = %(">) + class_attribute :helpers class_attribute :_routes diff --git a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb index 52f0e9f5bd..03aab444f8 100644 --- a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb +++ b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb @@ -46,11 +46,8 @@ module ActionView # # == TODO # - # * Add streaming support in the controllers with no-cache settings - # * What should happen when an error happens? # * Support streaming from child templates, partials and so on. - # * Support on sprockets async JS load? - # + # * Integrate exceptions with exceptron class StreamingTemplateRenderer < TemplateRenderer #:nodoc: # A valid Rack::Body (i.e. it responds to each). # It is initialized with a block that, when called, starts @@ -61,7 +58,11 @@ module ActionView end def each(&block) - @start.call(block) + begin + @start.call(block) + rescue + block.call ActionView::Base.streaming_completion_on_exception + end self end end diff --git a/actionpack/test/controller/new_base/render_streaming_test.rb b/actionpack/test/controller/new_base/render_streaming_test.rb index ffc4b331ec..b8df5ec4e8 100644 --- a/actionpack/test/controller/new_base/render_streaming_test.rb +++ b/actionpack/test/controller/new_base/render_streaming_test.rb @@ -4,7 +4,9 @@ module RenderStreaming class BasicController < ActionController::Base self.view_paths = [ActionView::FixtureResolver.new( "render_streaming/basic/hello_world.html.erb" => "Hello world", - "layouts/application.html.erb" => "<%= yield %>, I'm here!" + "render_streaming/basic/boom.html.erb" => "<%= nil.invalid! %>", + "layouts/application.html.erb" => "<%= yield %>, I'm here!", + "layouts/boom.html.erb" => "\"<%= yield %>" )] layout "application" @@ -13,6 +15,14 @@ module RenderStreaming def hello_world end + def layout_exception + render :action => "hello_world", :stream => true, :layout => "boom" + end + + def template_exception + render :action => "boom", :stream => true + end + def skip render :action => "hello_world", :stream => false end @@ -61,6 +71,18 @@ module RenderStreaming assert_body "Hello world, I'm here!" end + test "rendering with layout exception" do + get "/render_streaming/basic/layout_exception" + assert_body "d\r\n\r\n0\r\n\r\n" + assert_streaming! + end + + test "rendering with template exception" do + get "/render_streaming/basic/template_exception" + assert_body "4e\r\n\">\r\n0\r\n\r\n" + assert_streaming! + end + def assert_streaming!(cache="no-cache") assert_status 200 assert_equal nil, headers["Content-Length"] -- cgit v1.2.3