rescue_test.rb 8.5 KB
Newer Older
1
require 'abstract_unit'
J
Jeremy Kemper 已提交
2

3 4 5 6 7 8 9 10 11 12 13 14 15 16
module ActionDispatch
  class ShowExceptions
    private
      def public_path
        "#{FIXTURE_LOAD_PATH}/public"
      end

      # Silence logger
      def logger
        nil
      end
  end
end

J
Jeremy Kemper 已提交
17
class RescueController < ActionController::Base
18 19
  class NotAuthorized < StandardError
  end
20 21
  class NotAuthorizedToRescueAsString < StandardError
  end
22 23 24

  class RecordInvalid < StandardError
  end
25 26
  class RecordInvalidToRescueAsString < StandardError
  end
27

28 29
  class NotAllowed < StandardError
  end
30 31
  class NotAllowedToRescueAsString < StandardError
  end
32 33 34

  class InvalidRequest < StandardError
  end
35 36
  class InvalidRequestToRescueAsString < StandardError
  end
37 38 39

  class BadGateway < StandardError
  end
40 41
  class BadGatewayToRescueAsString < StandardError
  end
42 43 44

  class ResourceUnavailable < StandardError
  end
45 46 47 48 49
  class ResourceUnavailableToRescueAsString < StandardError
  end

  # We use a fully-qualified name in some strings, and a relative constant
  # name in some other to test correct handling of both cases.
50

51
  rescue_from NotAuthorized, :with => :deny_access
52 53
  rescue_from 'RescueController::NotAuthorizedToRescueAsString', :with => :deny_access

54
  rescue_from RecordInvalid, :with => :show_errors
55
  rescue_from 'RescueController::RecordInvalidToRescueAsString', :with => :show_errors
56

57
  rescue_from NotAllowed, :with => proc { head :forbidden }
58 59
  rescue_from 'RescueController::NotAllowedToRescueAsString', :with => proc { head :forbidden }

60
  rescue_from InvalidRequest, :with => proc { |exception| render :text => exception.message }
61
  rescue_from 'InvalidRequestToRescueAsString', :with => proc { |exception| render :text => exception.message }
62 63 64 65

  rescue_from BadGateway do
    head :status => 502
  end
66 67 68
  rescue_from 'BadGatewayToRescueAsString' do
    head :status => 502
  end
69 70 71 72

  rescue_from ResourceUnavailable do |exception|
    render :text => exception.message
  end
73 74 75
  rescue_from 'ResourceUnavailableToRescueAsString' do |exception|
    render :text => exception.message
  end
76

77 78 79 80 81
  # This is a Dispatcher exception and should be in ApplicationController.
  rescue_from ActionController::RoutingError do
    render :text => 'no way'
  end

82 83 84 85 86
  before_filter(:only => :before_filter_raises) { raise 'umm nice' }

  def before_filter_raises
  end

J
Jeremy Kemper 已提交
87 88 89 90
  def raises
    render :text => 'already rendered'
    raise "don't panic!"
  end
91 92 93 94

  def method_not_allowed
    raise ActionController::MethodNotAllowed.new(:get, :head, :put)
  end
95

96 97 98
  def not_implemented
    raise ActionController::NotImplemented.new(:get, :put)
  end
99 100 101 102

  def not_authorized
    raise NotAuthorized
  end
103 104 105
  def not_authorized_raise_as_string
    raise NotAuthorizedToRescueAsString
  end
106

107 108 109
  def not_allowed
    raise NotAllowed
  end
110 111 112
  def not_allowed_raise_as_string
    raise NotAllowedToRescueAsString
  end
113 114 115 116

  def invalid_request
    raise InvalidRequest
  end
117 118 119
  def invalid_request_raise_as_string
    raise InvalidRequestToRescueAsString
  end
120

121 122 123
  def record_invalid
    raise RecordInvalid
  end
124 125 126
  def record_invalid_raise_as_string
    raise RecordInvalidToRescueAsString
  end
127

128 129 130
  def bad_gateway
    raise BadGateway
  end
131 132 133
  def bad_gateway_raise_as_string
    raise BadGatewayToRescueAsString
  end
134 135 136 137

  def resource_unavailable
    raise ResourceUnavailable
  end
138 139 140
  def resource_unavailable_raise_as_string
    raise ResourceUnavailableToRescueAsString
  end
141

142 143 144 145 146 147 148
  def missing_template
  end

  protected
    def deny_access
      head :forbidden
    end
J
Jeremy Kemper 已提交
149

150 151 152 153
    def show_errors(exception)
      head :unprocessable_entity
    end
end
J
Jeremy Kemper 已提交
154

155
class ExceptionInheritanceRescueController < ActionController::Base
156

157
  class ParentException < StandardError
158 159
  end

160
  class ChildException < ParentException
J
Jeremy Kemper 已提交
161 162
  end

163
  class GrandchildException < ChildException
J
Jeremy Kemper 已提交
164 165
  end

166 167 168
  rescue_from ChildException,      :with => lambda { head :ok }
  rescue_from ParentException,     :with => lambda { head :created }
  rescue_from GrandchildException, :with => lambda { head :no_content }
J
Jeremy Kemper 已提交
169

170 171
  def raise_parent_exception
    raise ParentException
J
Jeremy Kemper 已提交
172 173
  end

174 175
  def raise_child_exception
    raise ChildException
176 177
  end

178 179
  def raise_grandchild_exception
    raise GrandchildException
J
Jeremy Kemper 已提交
180
  end
181
end
J
Jeremy Kemper 已提交
182

183 184 185 186
class ExceptionInheritanceRescueControllerTest < ActionController::TestCase
  def test_bottom_first
    get :raise_grandchild_exception
    assert_response :no_content
J
Jeremy Kemper 已提交
187 188
  end

189 190 191
  def test_inheritance_works
    get :raise_child_exception
    assert_response :created
J
Jeremy Kemper 已提交
192
  end
193
end
J
Jeremy Kemper 已提交
194

195 196
class ControllerInheritanceRescueController < ExceptionInheritanceRescueController
  class FirstExceptionInChildController < StandardError
J
Jeremy Kemper 已提交
197 198
  end

199
  class SecondExceptionInChildController < StandardError
200 201
  end

202
  rescue_from FirstExceptionInChildController, 'SecondExceptionInChildController', :with => lambda { head :gone }
J
Jeremy Kemper 已提交
203

204 205
  def raise_first_exception_in_child_controller
    raise FirstExceptionInChildController
J
Jeremy Kemper 已提交
206 207
  end

208 209
  def raise_second_exception_in_child_controller
    raise SecondExceptionInChildController
J
Jeremy Kemper 已提交
210
  end
211
end
J
Jeremy Kemper 已提交
212

213 214 215 216
class ControllerInheritanceRescueControllerTest < ActionController::TestCase
  def test_first_exception_in_child_controller
    get :raise_first_exception_in_child_controller
    assert_response :gone
J
Jeremy Kemper 已提交
217 218
  end

219 220 221
  def test_second_exception_in_child_controller
    get :raise_second_exception_in_child_controller
    assert_response :gone
J
Jeremy Kemper 已提交
222 223
  end

224 225 226
  def test_exception_in_parent_controller
    get :raise_parent_exception
    assert_response :created
227
  end
228
end
229

230
class RescueControllerTest < ActionController::TestCase
231 232 233 234
  def test_rescue_handler
    get :not_authorized
    assert_response :forbidden
  end
235 236 237 238
  def test_rescue_handler_string
    get :not_authorized_raise_as_string
    assert_response :forbidden
  end
239 240 241 242 243

  def test_rescue_handler_with_argument
    @controller.expects(:show_errors).once.with { |e| e.is_a?(Exception) }
    get :record_invalid
  end
244 245 246 247
  def test_rescue_handler_with_argument_as_string
    @controller.expects(:show_errors).once.with { |e| e.is_a?(Exception) }
    get :record_invalid_raise_as_string
  end
248

249 250 251 252
  def test_proc_rescue_handler
    get :not_allowed
    assert_response :forbidden
  end
253 254 255 256
  def test_proc_rescue_handler_as_string
    get :not_allowed_raise_as_string
    assert_response :forbidden
  end
257 258 259 260 261

  def test_proc_rescue_handle_with_argument
    get :invalid_request
    assert_equal "RescueController::InvalidRequest", @response.body
  end
262 263 264 265
  def test_proc_rescue_handle_with_argument_as_string
    get :invalid_request_raise_as_string
    assert_equal "RescueController::InvalidRequestToRescueAsString", @response.body
  end
266 267 268 269 270

  def test_block_rescue_handler
    get :bad_gateway
    assert_response 502
  end
271 272 273 274
  def test_block_rescue_handler_as_string
    get :bad_gateway_raise_as_string
    assert_response 502
  end
275 276 277 278 279 280

  def test_block_rescue_handler_with_argument
    get :resource_unavailable
    assert_equal "RescueController::ResourceUnavailable", @response.body
  end

281 282 283 284
  def test_block_rescue_handler_with_argument_as_string
    get :resource_unavailable_raise_as_string
    assert_equal "RescueController::ResourceUnavailableToRescueAsString", @response.body
  end
285 286
end

J
Joshua Peek 已提交
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
class RescueTest < ActionController::IntegrationTest
  class TestController < ActionController::Base
    class RecordInvalid < StandardError
      def message
        'invalid'
      end
    end
    rescue_from RecordInvalid, :with => :show_errors

    def foo
      render :text => "foo"
    end

    def invalid
      raise RecordInvalid
    end

    def b00m
      raise 'b00m'
    end

    protected
      def show_errors(exception)
        render :text => exception.message
      end
  end

  test 'normal request' do
    with_test_routing do
      get '/foo'
      assert_equal 'foo', response.body
    end
  end

  test 'rescue exceptions inside controller' do
    with_test_routing do
      get '/invalid'
      assert_equal 'invalid', response.body
    end
  end

328
  test 'rescue routing exceptions' do
329
    @app = ActionDispatch::Rescue.new(ActionController::Routing::Routes) do
330
      rescue_from ActionController::RoutingError, lambda { |env| [200, {"Content-Type" => "text/html"}, ["Gotcha!"]] }
331 332 333 334 335
    end

    get '/b00m'
    assert_equal "Gotcha!", response.body
  end
J
Joshua Peek 已提交
336 337

  test 'unrescued exception' do
338
    @app = ActionDispatch::Rescue.new(ActionController::Routing::Routes)
339
    assert_raise(ActionController::RoutingError) { get '/b00m' }
J
Joshua Peek 已提交
340 341 342 343 344 345
  end

  private
    def with_test_routing
      with_routing do |set|
        set.draw do |map|
346 347 348
          match 'foo', :to => ::RescueTest::TestController.action(:foo)
          match 'invalid', :to => ::RescueTest::TestController.action(:invalid)
          match 'b00m', :to => ::RescueTest::TestController.action(:b00m)
J
Joshua Peek 已提交
349 350 351 352 353
        end
        yield
      end
    end
end