Permalink
Browse files

Syntax errors and other exceptions thrown outside of an action are no…

…w gracefully handled by the dispatcher

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@51 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
1 parent ed14042 commit 0ffb6c16258b5c39a7417f4563edf0fc7542c9ae @dhh dhh committed Dec 6, 2004
View
@@ -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/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 @@
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_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 @@ class Base
@@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 @@ class << self
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 @@ def controller_class_name
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 @@ def template_path_for_local_rescue(exception)
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,18 +1,16 @@
<%
- 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
%>
<h1>
<%=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
View
@@ -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 @@ def self.dispatch(cgi = CGI.new, session_options = DEFAULT_SESSION_OPTIONS, erro
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 @@ def generate
end
end
- # Generate model, unit test, and fixtures.
+ # Generate model, unit test, and fixtures.
class Model < Base
def generate
@@ -85,7 +85,6 @@ def handle_file(req, res)
res.set_error(err)
return true
rescue => err
- p err
return false
end
end

0 comments on commit 0ffb6c1

Please sign in to comment.