aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2011-04-19 12:25:01 +0200
committerJosé Valim <jose.valim@gmail.com>2011-04-19 12:26:11 +0200
commitb398520c1406824efd12df6bb57996aa9781f876 (patch)
treecad818bf1981a31eb10f257692167f10575aafb0
parenta66c91723565d37969de4cb46baa50fb8865b02a (diff)
downloadrails-b398520c1406824efd12df6bb57996aa9781f876.tar.gz
rails-b398520c1406824efd12df6bb57996aa9781f876.tar.bz2
rails-b398520c1406824efd12df6bb57996aa9781f876.zip
Output a redirect to the 500 page if something happens when streaming.
Currently, we output: "><script type="text/javascript">window.location = "/500.html"</script></html>
-rw-r--r--actionpack/lib/action_view/base.rb6
-rw-r--r--actionpack/lib/action_view/renderer/streaming_template_renderer.rb11
-rw-r--r--actionpack/test/controller/new_base/render_streaming_test.rb24
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| "<div class=\"field_with_errors\">#{html_tag}</div>".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 = %("><script type="text/javascript">window.location = "/500.html"</script></html>)
+
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" => "<body class=\"<%= nil.invalid! %>\"<%= yield %></body>"
)]
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<body class=\"\r\n4e\r\n\"><script type=\"text/javascript\">window.location = \"/500.html\"</script></html>\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\"><script type=\"text/javascript\">window.location = \"/500.html\"</script></html>\r\n0\r\n\r\n"
+ assert_streaming!
+ end
+
def assert_streaming!(cache="no-cache")
assert_status 200
assert_equal nil, headers["Content-Length"]