mirror of https://github.com/rails/rails
Syntax errors and other exceptions thrown outside of an action are now gracefully handled by the dispatcher
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@51 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
ed14042fea
commit
0ffb6c1625
|
@ -325,7 +325,6 @@ methods:
|
|||
|
||||
def create
|
||||
@post = Post.create(@params["post"])
|
||||
@post.save
|
||||
redirect_to :action => "display", :id => @post.id
|
||||
end
|
||||
end
|
||||
|
|
|
@ -32,9 +32,9 @@ require 'action_controller/benchmarking'
|
|||
require 'action_controller/filters'
|
||||
require 'action_controller/layout'
|
||||
require 'action_controller/flash'
|
||||
require 'action_controller/dependencies'
|
||||
require 'action_controller/scaffolding'
|
||||
require 'action_controller/helpers'
|
||||
require 'action_controller/dependencies'
|
||||
require 'action_controller/cookies'
|
||||
require 'action_controller/cgi_process'
|
||||
|
||||
|
@ -44,9 +44,9 @@ ActionController::Base.class_eval do
|
|||
include ActionController::Flash
|
||||
include ActionController::Benchmarking
|
||||
include ActionController::Rescue
|
||||
include ActionController::Dependencies
|
||||
include ActionController::Scaffolding
|
||||
include ActionController::Helpers
|
||||
include ActionController::Dependencies
|
||||
include ActionController::Cookies
|
||||
end
|
||||
|
||||
|
|
|
@ -5,10 +5,6 @@ require 'action_controller/support/class_attribute_accessors'
|
|||
require 'action_controller/support/class_inheritable_attributes'
|
||||
require 'action_controller/support/inflector'
|
||||
|
||||
unless Object.respond_to?(:require_dependency)
|
||||
Object.send(:define_method, :require_dependency) { |file_name| ActionController::Base.require_dependency(file_name) }
|
||||
end
|
||||
|
||||
module ActionController #:nodoc:
|
||||
class ActionControllerError < StandardError #:nodoc:
|
||||
end
|
||||
|
@ -197,12 +193,6 @@ module ActionController #:nodoc:
|
|||
@@consider_all_requests_local = true
|
||||
cattr_accessor :consider_all_requests_local
|
||||
|
||||
# When turned on (which is default), all dependencies are included using "load". This mean that any change is instant in cached
|
||||
# environments like mod_ruby or FastCGI. When set to false, "require" is used, which is faster but requires server restart to
|
||||
# be effective.
|
||||
@@reload_dependencies = true
|
||||
cattr_accessor :reload_dependencies
|
||||
|
||||
# Template root determines the base from which template references will be made. So a call to render("test/template")
|
||||
# will be converted to "#{template_root}/test/template.rhtml".
|
||||
cattr_accessor :template_root
|
||||
|
@ -248,7 +238,7 @@ module ActionController #:nodoc:
|
|||
def process(request, response) #:nodoc:
|
||||
new.process(request, response)
|
||||
end
|
||||
|
||||
|
||||
# Converts the class name from something like "OneModule::TwoModule::NeatController" to "NeatController".
|
||||
def controller_class_name
|
||||
Inflector.demodulize(name)
|
||||
|
@ -258,22 +248,17 @@ module ActionController #:nodoc:
|
|||
def controller_name
|
||||
Inflector.underscore(controller_class_name.sub(/Controller/, ""))
|
||||
end
|
||||
|
||||
# Loads the <tt>file_name</tt> if reload_dependencies is true or requires if it's false.
|
||||
def require_dependency(file_name)
|
||||
reload_dependencies ? silence_warnings { load("#{file_name}.rb") } : require(file_name)
|
||||
end
|
||||
end
|
||||
|
||||
public
|
||||
# Extracts the action_name from the request parameters and performs that action.
|
||||
def process(request, response) #:nodoc:
|
||||
def process(request, response, method = :perform_action, *arguments) #:nodoc:
|
||||
initialize_template_class(response)
|
||||
assign_shortcuts(request, response)
|
||||
initialize_current_url
|
||||
|
||||
log_processing unless logger.nil?
|
||||
perform_action
|
||||
send(method, *arguments)
|
||||
close_session
|
||||
|
||||
return @response
|
||||
|
|
|
@ -1,11 +1,29 @@
|
|||
unless Object.respond_to?(:require_dependency)
|
||||
Object.send(:define_method, :require_dependency) { |file_name| ActionController::Base.require_dependency(file_name) }
|
||||
end
|
||||
|
||||
module ActionController #:nodoc:
|
||||
module Dependencies #:nodoc:
|
||||
def self.append_features(base)
|
||||
super
|
||||
|
||||
base.class_eval do
|
||||
# When turned on (which is default), all dependencies are included using "load". This mean that any change is instant in cached
|
||||
# environments like mod_ruby or FastCGI. When set to false, "require" is used, which is faster but requires server restart to
|
||||
# be effective.
|
||||
@@reload_dependencies = true
|
||||
cattr_accessor :reload_dependencies
|
||||
end
|
||||
|
||||
base.extend(ClassMethods)
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# Loads the <tt>file_name</tt> if reload_dependencies is true or requires if it's false.
|
||||
def require_dependency(file_name)
|
||||
reload_dependencies ? silence_warnings { load("#{file_name}.rb") } : require(file_name)
|
||||
end
|
||||
|
||||
def model(*models)
|
||||
require_dependencies(:model, models)
|
||||
depend_on(:model, models)
|
||||
|
|
|
@ -8,12 +8,19 @@ module ActionController #:nodoc:
|
|||
module Rescue
|
||||
def self.append_features(base) #:nodoc:
|
||||
super
|
||||
base.extend(ClassMethods)
|
||||
base.class_eval do
|
||||
alias_method :perform_action_without_rescue, :perform_action
|
||||
alias_method :perform_action, :perform_action_with_rescue
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def process_with_exception(request, response, exception)
|
||||
new.process(request, response, :rescue_action, exception)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
# Exception handler called when the performance of an action raises an exception.
|
||||
def rescue_action(exception)
|
||||
|
@ -87,8 +94,7 @@ module ActionController #:nodoc:
|
|||
end
|
||||
|
||||
def clean_backtrace(exception)
|
||||
base_dir = File.expand_path(File.dirname(__FILE__) + "/../../../../")
|
||||
exception.backtrace.collect { |line| line.gsub(base_dir, "").gsub("/public/../config/environments/../../", "").gsub("/public/../", "") }
|
||||
exception.backtrace.collect { |line| Object.const_defined?(:RAILS_ROOT) ? line.gsub(RAILS_ROOT, "") : line }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
<%
|
||||
base_dir = File.expand_path(File.dirname(__FILE__))
|
||||
|
||||
request_parameters_without_action = @request.parameters.clone
|
||||
request_parameters_without_action.delete("action")
|
||||
request_parameters_without_action.delete("controller")
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
<%
|
||||
base_dir = File.expand_path(File.dirname(__FILE__))
|
||||
|
||||
clean_backtrace = @exception.backtrace.collect { |line| line.gsub(base_dir, "").gsub("/../config/environments/../../", "") }
|
||||
app_trace = clean_backtrace.reject { |line| line[0..6] == "vendor/" || line.include?("dispatch.cgi") }
|
||||
clean_backtrace = @exception.backtrace.collect { |line| Object.const_defined?(:RAILS_ROOT) ? line.gsub(RAILS_ROOT, "") : line }
|
||||
app_trace = clean_backtrace.reject { |line| line =~ /(vendor|dispatch|ruby)/ }
|
||||
framework_trace = clean_backtrace - app_trace
|
||||
%>
|
||||
|
||||
|
@ -10,9 +8,9 @@
|
|||
<%=h @exception.class.to_s %> in
|
||||
<%=h @request.parameters["controller"].capitalize %>#<%=h @request.parameters["action"] %>
|
||||
</h1>
|
||||
<p><%=h @exception.message %></p>
|
||||
<p><%=h Object.const_defined?(:RAILS_ROOT) ? @exception.message.gsub(RAILS_ROOT, "") : @exception.message %></p>
|
||||
|
||||
<% unless app_trace.empty? %><pre><code><%=h app_trace.collect { |line| line.gsub("/../", "") }.join("\n") %></code></pre><% end %>
|
||||
<% unless app_trace.empty? %><pre><code><%=h app_trace.join("\n") %></code></pre><% end %>
|
||||
|
||||
<% unless framework_trace.empty? %>
|
||||
<a href="#" onclick="document.getElementById('framework_trace').style.display='block'; return false;">Show framework trace</a>
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
<%
|
||||
base_dir = File.expand_path(File.dirname(__FILE__))
|
||||
|
||||
framework_trace = @exception.original_exception.backtrace.collect do |line|
|
||||
line.gsub(base_dir, "").gsub("/../config/environments/../../", "")
|
||||
end
|
||||
%>
|
||||
|
||||
<h1>
|
||||
<%=h @exception.original_exception.class.to_s %> in
|
||||
<%=h @request.parameters["controller"].capitalize %>#<%=h @request.parameters["action"] %>
|
||||
|
@ -21,6 +13,6 @@
|
|||
<p><%=h @exception.sub_template_message %></p>
|
||||
|
||||
<a href="#" onclick="document.getElementById('framework_trace').style.display='block'">Show template trace</a>
|
||||
<pre id="framework_trace" style="display:none"><code><%=h framework_trace.join("\n") %></code></pre>
|
||||
<pre id="framework_trace" style="display:none"><code><%=h @exception.original_exception.backtrace.collect { |line| Object.const_defined?(:RAILS_ROOT) ? line.gsub(RAILS_ROOT, "") : line }.join("\n") %></code></pre>
|
||||
|
||||
<%= render_file(@rescues_path + "/_request_and_response.rhtml", false) %>
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
ruby public/dispatch.servlet
|
|
@ -24,7 +24,7 @@
|
|||
class Dispatcher
|
||||
DEFAULT_SESSION_OPTIONS = { "database_manager" => CGI::Session::PStore, "prefix" => "ruby_sess.", "session_path" => "/" }
|
||||
|
||||
def self.dispatch(cgi = CGI.new, session_options = DEFAULT_SESSION_OPTIONS, error_page = nil)
|
||||
def self.dispatch(cgi = CGI.new, session_options = DEFAULT_SESSION_OPTIONS)
|
||||
begin
|
||||
request = ActionController::CgiRequest.new(cgi, session_options)
|
||||
response = ActionController::CgiResponse.new(cgi)
|
||||
|
@ -35,14 +35,8 @@ class Dispatcher
|
|||
require_dependency(controller_path(controller_name, module_name))
|
||||
|
||||
controller_class(controller_name).process(request, response).out
|
||||
rescue Object => e
|
||||
begin
|
||||
ActionController::Base.logger.info "\n\nException throw during dispatch: #{e.message}\n#{e.backtrace.join("\n")}"
|
||||
rescue Exception
|
||||
# Couldn't log error
|
||||
end
|
||||
|
||||
if error_page then cgi.out{ IO.readlines(error_page) } else raise e end
|
||||
rescue Object => exception
|
||||
ActionController::Base.process_with_exception(request, response, exception).out
|
||||
ensure
|
||||
ActiveRecord::Base.reset_associations_loaded
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ module Generator
|
|||
end
|
||||
end
|
||||
|
||||
# Generate model, unit test, and fixtures.
|
||||
# Generate model, unit test, and fixtures.
|
||||
class Model < Base
|
||||
def generate
|
||||
|
||||
|
|
|
@ -85,7 +85,6 @@ class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet
|
|||
res.set_error(err)
|
||||
return true
|
||||
rescue => err
|
||||
p err
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue