aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller/metal
diff options
context:
space:
mode:
authorSean Griffin <sean@seantheprogrammer.com>2013-03-07 15:49:03 -0700
committerSean Griffin <sean@seantheprogrammer.com>2013-03-18 10:41:24 -0600
commitc01d080fd6b02de696c46547bdb0e95f0f62386b (patch)
treec55243223e63e4094919349d40200a24fad2ed8e /actionpack/lib/action_controller/metal
parenteb32b3659d3ead36e66efe8ef2ced126110311a4 (diff)
downloadrails-c01d080fd6b02de696c46547bdb0e95f0f62386b.tar.gz
rails-c01d080fd6b02de696c46547bdb0e95f0f62386b.tar.bz2
rails-c01d080fd6b02de696c46547bdb0e95f0f62386b.zip
Exception handling for controllers using ActionController::Live
Any exceptions that occured at the view or controller level for a controller using ActionController::Live would cause the server to either hang with an open socket indefinitely, or immediately crash (depending on whether the server was launched with rails s or directly). Changed the behavior of exceptions to act the same as streaming templates for html requests, and allow for an on_error callback if needed.
Diffstat (limited to 'actionpack/lib/action_controller/metal')
-rw-r--r--actionpack/lib/action_controller/metal/live.rb28
1 files changed, 28 insertions, 0 deletions
diff --git a/actionpack/lib/action_controller/metal/live.rb b/actionpack/lib/action_controller/metal/live.rb
index fb664a69dd..0a77352e57 100644
--- a/actionpack/lib/action_controller/metal/live.rb
+++ b/actionpack/lib/action_controller/metal/live.rb
@@ -56,6 +56,14 @@ module ActionController
super
@buf.push nil
end
+
+ def on_error(&block)
+ @error_callback = block
+ end
+
+ def call_on_error
+ @error_callback.call
+ end
end
class Response < ActionDispatch::Response #:nodoc: all
@@ -121,6 +129,16 @@ module ActionController
begin
super(name)
+ rescue => e
+ begin
+ @_response.stream.write(ActionView::Base.streaming_completion_on_exception) if request.format == :html
+ @_response.stream.call_on_error
+ rescue => exceptionception
+ log_error(exceptionception)
+ ensure
+ log_error(e)
+ @_response.stream.close
+ end
ensure
@_response.commit!
end
@@ -129,6 +147,16 @@ module ActionController
@_response.await_commit
end
+ def log_error(exception)
+ 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
+
def response_body=(body)
super
response.stream.close if response