2017-07-24 16:20:53 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2016-08-06 12:54:50 -04:00
|
|
|
require "abstract_unit"
|
2007-01-13 02:14:46 -05:00
|
|
|
|
2006-11-12 21:03:50 -05:00
|
|
|
class RescueController < ActionController::Base
|
2007-09-23 17:56:22 -04:00
|
|
|
class NotAuthorized < StandardError
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
class NotAuthorizedToRescueAsString < StandardError
|
|
|
|
end
|
2007-09-23 17:56:22 -04:00
|
|
|
|
|
|
|
class RecordInvalid < StandardError
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
class RecordInvalidToRescueAsString < StandardError
|
|
|
|
end
|
2007-09-23 17:56:22 -04:00
|
|
|
|
2007-10-09 22:34:42 -04:00
|
|
|
class NotAllowed < StandardError
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
class NotAllowedToRescueAsString < StandardError
|
|
|
|
end
|
2007-10-09 22:34:42 -04:00
|
|
|
|
|
|
|
class InvalidRequest < StandardError
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
class InvalidRequestToRescueAsString < StandardError
|
|
|
|
end
|
2007-10-09 22:34:42 -04:00
|
|
|
|
|
|
|
class BadGateway < StandardError
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
class BadGatewayToRescueAsString < StandardError
|
|
|
|
end
|
2007-10-09 22:34:42 -04:00
|
|
|
|
|
|
|
class ResourceUnavailable < StandardError
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
class ResourceUnavailableToRescueAsString < StandardError
|
|
|
|
end
|
|
|
|
|
2021-03-24 18:53:27 -04:00
|
|
|
wrap_parameters format: :json
|
|
|
|
|
2017-09-06 08:49:04 -04:00
|
|
|
# We use a fully qualified name in some strings, and a relative constant
|
2007-11-06 01:02:24 -05:00
|
|
|
# name in some other to test correct handling of both cases.
|
2007-10-09 22:34:42 -04:00
|
|
|
|
2016-08-06 13:35:13 -04:00
|
|
|
rescue_from NotAuthorized, with: :deny_access
|
|
|
|
rescue_from "RescueController::NotAuthorizedToRescueAsString", with: :deny_access
|
2007-11-06 01:02:24 -05:00
|
|
|
|
2016-08-06 13:35:13 -04:00
|
|
|
rescue_from RecordInvalid, with: :show_errors
|
|
|
|
rescue_from "RescueController::RecordInvalidToRescueAsString", with: :show_errors
|
2007-09-23 17:56:22 -04:00
|
|
|
|
2016-08-06 13:35:13 -04:00
|
|
|
rescue_from NotAllowed, with: proc { head :forbidden }
|
|
|
|
rescue_from "RescueController::NotAllowedToRescueAsString", with: proc { head :forbidden }
|
2007-11-06 01:02:24 -05:00
|
|
|
|
2015-07-17 21:48:00 -04:00
|
|
|
rescue_from InvalidRequest, with: proc { |exception| render plain: exception.message }
|
2016-08-06 12:54:50 -04:00
|
|
|
rescue_from "InvalidRequestToRescueAsString", with: proc { |exception| render plain: exception.message }
|
2007-10-09 22:34:42 -04:00
|
|
|
|
|
|
|
rescue_from BadGateway do
|
2015-06-15 16:53:45 -04:00
|
|
|
head 502
|
2007-10-09 22:34:42 -04:00
|
|
|
end
|
2016-08-06 12:54:50 -04:00
|
|
|
rescue_from "BadGatewayToRescueAsString" do
|
2015-06-15 16:53:45 -04:00
|
|
|
head 502
|
2007-11-06 01:02:24 -05:00
|
|
|
end
|
2007-10-09 22:34:42 -04:00
|
|
|
|
|
|
|
rescue_from ResourceUnavailable do |exception|
|
2015-07-17 21:48:00 -04:00
|
|
|
render plain: exception.message
|
2007-10-09 22:34:42 -04:00
|
|
|
end
|
2016-08-06 12:54:50 -04:00
|
|
|
rescue_from "ResourceUnavailableToRescueAsString" do |exception|
|
2015-07-17 21:48:00 -04:00
|
|
|
render plain: exception.message
|
2007-11-06 01:02:24 -05:00
|
|
|
end
|
2007-10-09 22:34:42 -04:00
|
|
|
|
2018-10-29 13:45:26 -04:00
|
|
|
rescue_from ActionDispatch::Http::Parameters::ParseError do
|
|
|
|
render plain: "parse error", status: :bad_request
|
|
|
|
end
|
|
|
|
|
2016-08-06 12:54:50 -04:00
|
|
|
before_action(only: :before_action_raises) { raise "umm nice" }
|
2008-12-30 21:06:56 -05:00
|
|
|
|
2012-12-07 15:24:56 -05:00
|
|
|
def before_action_raises
|
2008-12-30 21:06:56 -05:00
|
|
|
end
|
|
|
|
|
2007-09-23 17:56:22 -04:00
|
|
|
def not_authorized
|
|
|
|
raise NotAuthorized
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
def not_authorized_raise_as_string
|
|
|
|
raise NotAuthorizedToRescueAsString
|
|
|
|
end
|
2007-09-23 17:56:22 -04:00
|
|
|
|
2007-10-09 22:34:42 -04:00
|
|
|
def not_allowed
|
|
|
|
raise NotAllowed
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
def not_allowed_raise_as_string
|
|
|
|
raise NotAllowedToRescueAsString
|
|
|
|
end
|
2007-10-09 22:34:42 -04:00
|
|
|
|
|
|
|
def invalid_request
|
|
|
|
raise InvalidRequest
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
def invalid_request_raise_as_string
|
|
|
|
raise InvalidRequestToRescueAsString
|
|
|
|
end
|
2007-10-09 22:34:42 -04:00
|
|
|
|
2007-09-23 17:56:22 -04:00
|
|
|
def record_invalid
|
|
|
|
raise RecordInvalid
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
def record_invalid_raise_as_string
|
|
|
|
raise RecordInvalidToRescueAsString
|
|
|
|
end
|
2008-10-04 13:43:46 -04:00
|
|
|
|
2007-10-09 22:34:42 -04:00
|
|
|
def bad_gateway
|
|
|
|
raise BadGateway
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
def bad_gateway_raise_as_string
|
|
|
|
raise BadGatewayToRescueAsString
|
|
|
|
end
|
2007-10-09 22:34:42 -04:00
|
|
|
|
|
|
|
def resource_unavailable
|
|
|
|
raise ResourceUnavailable
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
def resource_unavailable_raise_as_string
|
|
|
|
raise ResourceUnavailableToRescueAsString
|
|
|
|
end
|
2007-10-09 22:34:42 -04:00
|
|
|
|
2018-10-29 13:45:26 -04:00
|
|
|
def arbitrary_action
|
|
|
|
params
|
|
|
|
render plain: "arbitrary action"
|
|
|
|
end
|
|
|
|
|
2007-09-23 17:56:22 -04:00
|
|
|
def missing_template
|
|
|
|
end
|
2010-08-14 01:13:00 -04:00
|
|
|
|
2016-03-11 12:14:50 -05:00
|
|
|
def exception_with_more_specific_handler_for_wrapper
|
|
|
|
raise RecordInvalid
|
|
|
|
rescue
|
|
|
|
raise NotAuthorized
|
|
|
|
end
|
|
|
|
|
|
|
|
def exception_with_more_specific_handler_for_cause
|
|
|
|
raise NotAuthorized
|
|
|
|
rescue
|
|
|
|
raise RecordInvalid
|
|
|
|
end
|
|
|
|
|
|
|
|
def exception_with_no_handler_for_wrapper
|
|
|
|
raise RecordInvalid
|
|
|
|
rescue
|
|
|
|
raise RangeError
|
|
|
|
end
|
|
|
|
|
2016-12-23 09:40:07 -05:00
|
|
|
private
|
2007-09-23 17:56:22 -04:00
|
|
|
def deny_access
|
|
|
|
head :forbidden
|
|
|
|
end
|
2006-11-12 21:03:50 -05:00
|
|
|
|
2007-09-23 17:56:22 -04:00
|
|
|
def show_errors(exception)
|
|
|
|
head :unprocessable_entity
|
|
|
|
end
|
|
|
|
end
|
2006-11-12 21:03:50 -05:00
|
|
|
|
2009-05-03 00:02:22 -04:00
|
|
|
class ExceptionInheritanceRescueController < ActionController::Base
|
|
|
|
class ParentException < StandardError
|
2008-12-30 21:06:56 -05:00
|
|
|
end
|
|
|
|
|
2009-05-03 00:02:22 -04:00
|
|
|
class ChildException < ParentException
|
2006-11-12 21:03:50 -05:00
|
|
|
end
|
|
|
|
|
2009-05-03 00:02:22 -04:00
|
|
|
class GrandchildException < ChildException
|
2006-11-12 21:03:50 -05:00
|
|
|
end
|
|
|
|
|
2016-08-06 13:35:13 -04:00
|
|
|
rescue_from ChildException, with: lambda { head :ok }
|
|
|
|
rescue_from ParentException, with: lambda { head :created }
|
|
|
|
rescue_from GrandchildException, with: lambda { head :no_content }
|
2006-11-12 21:03:50 -05:00
|
|
|
|
2009-05-03 00:02:22 -04:00
|
|
|
def raise_parent_exception
|
|
|
|
raise ParentException
|
2006-11-12 21:03:50 -05:00
|
|
|
end
|
|
|
|
|
2009-05-03 00:02:22 -04:00
|
|
|
def raise_child_exception
|
|
|
|
raise ChildException
|
2009-02-01 03:43:39 -05:00
|
|
|
end
|
|
|
|
|
2009-05-03 00:02:22 -04:00
|
|
|
def raise_grandchild_exception
|
|
|
|
raise GrandchildException
|
2006-11-12 21:03:50 -05:00
|
|
|
end
|
2009-05-03 00:02:22 -04:00
|
|
|
end
|
2006-11-12 21:03:50 -05:00
|
|
|
|
2009-05-03 00:02:22 -04:00
|
|
|
class ExceptionInheritanceRescueControllerTest < ActionController::TestCase
|
|
|
|
def test_bottom_first
|
|
|
|
get :raise_grandchild_exception
|
|
|
|
assert_response :no_content
|
2006-11-12 21:03:50 -05:00
|
|
|
end
|
|
|
|
|
2009-05-03 00:02:22 -04:00
|
|
|
def test_inheritance_works
|
|
|
|
get :raise_child_exception
|
|
|
|
assert_response :created
|
2006-11-12 21:03:50 -05:00
|
|
|
end
|
2009-05-03 00:02:22 -04:00
|
|
|
end
|
2006-11-12 21:03:50 -05:00
|
|
|
|
2009-05-03 00:02:22 -04:00
|
|
|
class ControllerInheritanceRescueController < ExceptionInheritanceRescueController
|
|
|
|
class FirstExceptionInChildController < StandardError
|
2006-11-12 21:03:50 -05:00
|
|
|
end
|
|
|
|
|
2009-05-03 00:02:22 -04:00
|
|
|
class SecondExceptionInChildController < StandardError
|
2007-07-11 19:32:02 -04:00
|
|
|
end
|
|
|
|
|
2016-08-06 13:35:13 -04:00
|
|
|
rescue_from FirstExceptionInChildController, "SecondExceptionInChildController", with: lambda { head :gone }
|
2006-11-12 21:03:50 -05:00
|
|
|
|
2009-05-03 00:02:22 -04:00
|
|
|
def raise_first_exception_in_child_controller
|
|
|
|
raise FirstExceptionInChildController
|
2006-11-12 21:03:50 -05:00
|
|
|
end
|
|
|
|
|
2009-05-03 00:02:22 -04:00
|
|
|
def raise_second_exception_in_child_controller
|
|
|
|
raise SecondExceptionInChildController
|
2006-11-12 21:03:50 -05:00
|
|
|
end
|
2009-05-03 00:02:22 -04:00
|
|
|
end
|
2006-11-12 21:03:50 -05:00
|
|
|
|
2009-05-03 00:02:22 -04:00
|
|
|
class ControllerInheritanceRescueControllerTest < ActionController::TestCase
|
|
|
|
def test_first_exception_in_child_controller
|
|
|
|
get :raise_first_exception_in_child_controller
|
|
|
|
assert_response :gone
|
2006-11-12 21:03:50 -05:00
|
|
|
end
|
|
|
|
|
2009-05-03 00:02:22 -04:00
|
|
|
def test_second_exception_in_child_controller
|
|
|
|
get :raise_second_exception_in_child_controller
|
|
|
|
assert_response :gone
|
2006-11-12 21:03:50 -05:00
|
|
|
end
|
|
|
|
|
2009-05-03 00:02:22 -04:00
|
|
|
def test_exception_in_parent_controller
|
|
|
|
get :raise_parent_exception
|
|
|
|
assert_response :created
|
2007-05-26 16:07:34 -04:00
|
|
|
end
|
2009-05-03 00:02:22 -04:00
|
|
|
end
|
2007-05-26 16:07:34 -04:00
|
|
|
|
2009-05-03 00:02:22 -04:00
|
|
|
class RescueControllerTest < ActionController::TestCase
|
2007-09-23 17:56:22 -04:00
|
|
|
def test_rescue_handler
|
|
|
|
get :not_authorized
|
|
|
|
assert_response :forbidden
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
def test_rescue_handler_string
|
|
|
|
get :not_authorized_raise_as_string
|
|
|
|
assert_response :forbidden
|
|
|
|
end
|
2007-09-23 17:56:22 -04:00
|
|
|
|
|
|
|
def test_rescue_handler_with_argument
|
2015-09-05 10:58:21 -04:00
|
|
|
assert_called_with @controller, :show_errors, [Exception] do
|
|
|
|
get :record_invalid
|
|
|
|
end
|
2007-09-23 17:56:22 -04:00
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
def test_rescue_handler_with_argument_as_string
|
2015-09-05 10:58:21 -04:00
|
|
|
assert_called_with @controller, :show_errors, [Exception] do
|
|
|
|
get :record_invalid_raise_as_string
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
end
|
2007-09-23 17:56:22 -04:00
|
|
|
|
2007-10-09 22:34:42 -04:00
|
|
|
def test_proc_rescue_handler
|
|
|
|
get :not_allowed
|
|
|
|
assert_response :forbidden
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
def test_proc_rescue_handler_as_string
|
|
|
|
get :not_allowed_raise_as_string
|
|
|
|
assert_response :forbidden
|
|
|
|
end
|
2007-10-09 22:34:42 -04:00
|
|
|
|
|
|
|
def test_proc_rescue_handle_with_argument
|
|
|
|
get :invalid_request
|
|
|
|
assert_equal "RescueController::InvalidRequest", @response.body
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
def test_proc_rescue_handle_with_argument_as_string
|
|
|
|
get :invalid_request_raise_as_string
|
|
|
|
assert_equal "RescueController::InvalidRequestToRescueAsString", @response.body
|
|
|
|
end
|
2007-10-09 22:34:42 -04:00
|
|
|
|
|
|
|
def test_block_rescue_handler
|
|
|
|
get :bad_gateway
|
|
|
|
assert_response 502
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
def test_block_rescue_handler_as_string
|
|
|
|
get :bad_gateway_raise_as_string
|
|
|
|
assert_response 502
|
|
|
|
end
|
2007-10-09 22:34:42 -04:00
|
|
|
|
|
|
|
def test_block_rescue_handler_with_argument
|
|
|
|
get :resource_unavailable
|
|
|
|
assert_equal "RescueController::ResourceUnavailable", @response.body
|
|
|
|
end
|
2007-11-06 01:02:24 -05:00
|
|
|
def test_block_rescue_handler_with_argument_as_string
|
|
|
|
get :resource_unavailable_raise_as_string
|
|
|
|
assert_equal "RescueController::ResourceUnavailableToRescueAsString", @response.body
|
|
|
|
end
|
2016-03-11 12:14:50 -05:00
|
|
|
|
2016-08-06 12:54:50 -04:00
|
|
|
test "rescue when wrapper has more specific handler than cause" do
|
2016-03-11 12:14:50 -05:00
|
|
|
get :exception_with_more_specific_handler_for_wrapper
|
2016-05-13 20:43:48 -04:00
|
|
|
assert_response :forbidden
|
2016-03-11 12:14:50 -05:00
|
|
|
end
|
|
|
|
|
2016-08-06 12:54:50 -04:00
|
|
|
test "rescue when cause has more specific handler than wrapper" do
|
2016-03-11 12:14:50 -05:00
|
|
|
get :exception_with_more_specific_handler_for_cause
|
|
|
|
assert_response :unprocessable_entity
|
|
|
|
end
|
|
|
|
|
2021-05-03 10:09:25 -04:00
|
|
|
test "rescue when cause has handler, but wrapper doesn't" do
|
2016-03-11 12:14:50 -05:00
|
|
|
get :exception_with_no_handler_for_wrapper
|
|
|
|
assert_response :unprocessable_entity
|
|
|
|
end
|
2018-10-29 13:45:26 -04:00
|
|
|
|
|
|
|
test "can rescue a ParseError" do
|
|
|
|
capture_log_output do
|
|
|
|
post :arbitrary_action, body: "{", as: :json
|
|
|
|
end
|
|
|
|
assert_response :bad_request
|
|
|
|
assert_equal "parse error", response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
def capture_log_output
|
|
|
|
output = StringIO.new
|
|
|
|
request.set_header "action_dispatch.logger", ActiveSupport::Logger.new(output)
|
|
|
|
yield
|
|
|
|
output.string
|
|
|
|
end
|
2009-04-21 22:11:23 -04:00
|
|
|
end
|
|
|
|
|
2010-09-24 20:15:52 -04:00
|
|
|
class RescueTest < ActionDispatch::IntegrationTest
|
2009-04-21 21:41:05 -04:00
|
|
|
class TestController < ActionController::Base
|
|
|
|
class RecordInvalid < StandardError
|
|
|
|
def message
|
2016-08-06 12:54:50 -04:00
|
|
|
"invalid"
|
2009-04-21 21:41:05 -04:00
|
|
|
end
|
|
|
|
end
|
2016-08-06 13:35:13 -04:00
|
|
|
rescue_from RecordInvalid, with: :show_errors
|
2009-04-21 21:41:05 -04:00
|
|
|
|
|
|
|
def foo
|
2015-07-17 21:48:00 -04:00
|
|
|
render plain: "foo"
|
2009-04-21 21:41:05 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def invalid
|
|
|
|
raise RecordInvalid
|
|
|
|
end
|
|
|
|
|
2016-12-23 09:40:07 -05:00
|
|
|
private
|
2009-04-21 21:41:05 -04:00
|
|
|
def show_errors(exception)
|
2015-07-17 21:48:00 -04:00
|
|
|
render plain: exception.message
|
2009-04-21 21:41:05 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-08-06 12:54:50 -04:00
|
|
|
test "normal request" do
|
2009-04-21 21:41:05 -04:00
|
|
|
with_test_routing do
|
2016-08-06 12:54:50 -04:00
|
|
|
get "/foo"
|
|
|
|
assert_equal "foo", response.body
|
2009-04-21 21:41:05 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-08-06 12:54:50 -04:00
|
|
|
test "rescue exceptions inside controller" do
|
2009-04-21 21:41:05 -04:00
|
|
|
with_test_routing do
|
2016-08-06 12:54:50 -04:00
|
|
|
get "/invalid"
|
|
|
|
assert_equal "invalid", response.body
|
2009-04-21 21:41:05 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
def with_test_routing
|
|
|
|
with_routing do |set|
|
2010-08-05 09:44:23 -04:00
|
|
|
set.draw do
|
2016-08-06 13:35:13 -04:00
|
|
|
get "foo", to: ::RescueTest::TestController.action(:foo)
|
|
|
|
get "invalid", to: ::RescueTest::TestController.action(:invalid)
|
2009-04-21 21:41:05 -04:00
|
|
|
end
|
|
|
|
yield
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|