From 0ffb6c16258b5c39a7417f4563edf0fc7542c9ae Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Mon, 6 Dec 2004 18:25:01 +0000 Subject: 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 --- actionpack/README | 1 - actionpack/lib/action_controller.rb | 4 ++-- actionpack/lib/action_controller/base.rb | 21 +++------------------ actionpack/lib/action_controller/dependencies.rb | 18 ++++++++++++++++++ actionpack/lib/action_controller/rescue.rb | 10 ++++++++-- .../templates/rescues/_request_and_response.rhtml | 2 -- .../templates/rescues/diagnostics.rhtml | 10 ++++------ .../templates/rescues/template_error.rhtml | 10 +--------- 8 files changed, 36 insertions(+), 40 deletions(-) (limited to 'actionpack') diff --git a/actionpack/README b/actionpack/README index d22ca0a701..33a6095133 100755 --- a/actionpack/README +++ b/actionpack/README @@ -325,7 +325,6 @@ methods: def create @post = Post.create(@params["post"]) - @post.save redirect_to :action => "display", :id => @post.id end end diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index af33d5fcff..8bfa6bd907 100755 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -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 diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index fda7c15174..e0c3fb01bf 100755 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -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 file_name 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 diff --git a/actionpack/lib/action_controller/dependencies.rb b/actionpack/lib/action_controller/dependencies.rb index f087354c63..5a3dd48f89 100644 --- a/actionpack/lib/action_controller/dependencies.rb +++ b/actionpack/lib/action_controller/dependencies.rb @@ -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 file_name 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) diff --git a/actionpack/lib/action_controller/rescue.rb b/actionpack/lib/action_controller/rescue.rb index e624888b64..328eca7fe4 100644 --- a/actionpack/lib/action_controller/rescue.rb +++ b/actionpack/lib/action_controller/rescue.rb @@ -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 diff --git a/actionpack/lib/action_controller/templates/rescues/_request_and_response.rhtml b/actionpack/lib/action_controller/templates/rescues/_request_and_response.rhtml index f1b4a2a1dd..d1703b0440 100644 --- a/actionpack/lib/action_controller/templates/rescues/_request_and_response.rhtml +++ b/actionpack/lib/action_controller/templates/rescues/_request_and_response.rhtml @@ -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") diff --git a/actionpack/lib/action_controller/templates/rescues/diagnostics.rhtml b/actionpack/lib/action_controller/templates/rescues/diagnostics.rhtml index 4eb1ed0439..c9ea00ef8f 100644 --- a/actionpack/lib/action_controller/templates/rescues/diagnostics.rhtml +++ b/actionpack/lib/action_controller/templates/rescues/diagnostics.rhtml @@ -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"] %> -

<%=h @exception.message %>

+

<%=h Object.const_defined?(:RAILS_ROOT) ? @exception.message.gsub(RAILS_ROOT, "") : @exception.message %>

-<% unless app_trace.empty? %>
<%=h app_trace.collect { |line| line.gsub("/../", "") }.join("\n") %>
<% end %> +<% unless app_trace.empty? %>
<%=h app_trace.join("\n") %>
<% end %> <% unless framework_trace.empty? %> Show framework trace diff --git a/actionpack/lib/action_controller/templates/rescues/template_error.rhtml b/actionpack/lib/action_controller/templates/rescues/template_error.rhtml index 326fd0b057..405a2e070a 100644 --- a/actionpack/lib/action_controller/templates/rescues/template_error.rhtml +++ b/actionpack/lib/action_controller/templates/rescues/template_error.rhtml @@ -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 -%> -

<%=h @exception.original_exception.class.to_s %> in <%=h @request.parameters["controller"].capitalize %>#<%=h @request.parameters["action"] %> @@ -21,6 +13,6 @@

<%=h @exception.sub_template_message %>

Show template trace - + <%= render_file(@rescues_path + "/_request_and_response.rhtml", false) %> -- cgit v1.2.3