aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/CHANGELOG2
-rw-r--r--actionpack/lib/action_controller/rescue.rb11
-rw-r--r--actionpack/test/controller/rescue_test.rb59
3 files changed, 68 insertions, 4 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 187b8d118c..504eca371e 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* rescue_from accepts :with => lambda { |exception| ... } or a normal block. #9827 [lifofifo]
+
* Add :status to redirect_to allowing users to choose their own response code without manually setting headers. #8297 [codahale, chasgrundy]
* Add link_to :back which uses your referrer with a fallback to a javascript link. #7366 [eventualbuddha, tarmo]
diff --git a/actionpack/lib/action_controller/rescue.rb b/actionpack/lib/action_controller/rescue.rb
index 4dbb3aca85..fa847a8274 100644
--- a/actionpack/lib/action_controller/rescue.rb
+++ b/actionpack/lib/action_controller/rescue.rb
@@ -71,10 +71,10 @@ module ActionController #:nodoc:
# exception.record.new_record? ? ...
# end
# end
- def rescue_from(*klasses)
+ def rescue_from(*klasses, &block)
options = klasses.extract_options!
- unless options.has_key?(:with) # allow nil
- raise ArgumentError, "Need a handler. Supply an options hash that has a :with key as the last argument."
+ unless options.has_key?(:with)
+ block_given? ? options[:with] = block : raise(ArgumentError, "Need a handler. Supply an options hash that has a :with key as the last argument.")
end
klasses.each do |klass|
@@ -192,8 +192,11 @@ module ActionController #:nodoc:
end
def handler_for_rescue(exception)
- if handler = rescue_handlers[exception.class.name]
+ case handler = rescue_handlers[exception.class.name]
+ when Symbol
method(handler)
+ when Proc
+ handler.bind(self)
end
end
diff --git a/actionpack/test/controller/rescue_test.rb b/actionpack/test/controller/rescue_test.rb
index f0d0526a36..cf4dcac029 100644
--- a/actionpack/test/controller/rescue_test.rb
+++ b/actionpack/test/controller/rescue_test.rb
@@ -9,9 +9,32 @@ class RescueController < ActionController::Base
class RecordInvalid < StandardError
end
+ class NotAllowed < StandardError
+ end
+
+ class InvalidRequest < StandardError
+ end
+
+ class BadGateway < StandardError
+ end
+
+ class ResourceUnavailable < StandardError
+ end
+
rescue_from NotAuthorized, :with => :deny_access
rescue_from RecordInvalid, :with => :show_errors
+ rescue_from NotAllowed, :with => proc { head :forbidden }
+ rescue_from InvalidRequest, :with => proc { |exception| render :text => exception.message }
+
+ rescue_from BadGateway do
+ head :status => 502
+ end
+
+ rescue_from ResourceUnavailable do |exception|
+ render :text => exception.message
+ end
+
def raises
render :text => 'already rendered'
raise "don't panic!"
@@ -29,10 +52,26 @@ class RescueController < ActionController::Base
raise NotAuthorized
end
+ def not_allowed
+ raise NotAllowed
+ end
+
+ def invalid_request
+ raise InvalidRequest
+ end
+
def record_invalid
raise RecordInvalid
end
+ def bad_gateway
+ raise BadGateway
+ end
+
+ def resource_unavailable
+ raise ResourceUnavailable
+ end
+
def missing_template
end
@@ -245,6 +284,26 @@ class RescueTest < Test::Unit::TestCase
get :record_invalid
end
+ def test_proc_rescue_handler
+ get :not_allowed
+ assert_response :forbidden
+ end
+
+ def test_proc_rescue_handle_with_argument
+ get :invalid_request
+ assert_equal "RescueController::InvalidRequest", @response.body
+ end
+
+ def test_block_rescue_handler
+ get :bad_gateway
+ assert_response 502
+ end
+
+ def test_block_rescue_handler_with_argument
+ get :resource_unavailable
+ assert_equal "RescueController::ResourceUnavailable", @response.body
+ end
+
protected
def with_all_requests_local(local = true)
old_local, ActionController::Base.consider_all_requests_local =