diff --git a/lib/sinatra/base.rb b/lib/sinatra/base.rb index 808afbc0..12a566d0 100644 --- a/lib/sinatra/base.rb +++ b/lib/sinatra/base.rb @@ -772,7 +772,8 @@ module Sinatra next base = base.superclass unless args = base.errors[key] return process_route(*args) end - false + return false unless key.respond_to? :superclass and key.superclass < Exception + error_block! key.superclass end def dump_errors!(boom) diff --git a/test/mapped_error_test.rb b/test/mapped_error_test.rb index 9bd1d6f8..2a8a7852 100644 --- a/test/mapped_error_test.rb +++ b/test/mapped_error_test.rb @@ -39,6 +39,36 @@ class MappedErrorTest < Test::Unit::TestCase assert_equal 'Exception!', body end + it 'walks down inheritance chain for errors' do + mock_app { + set :raise_errors, false + error(RuntimeError) { 'Exception!' } + get '/' do + raise FooError + end + } + + get '/' + assert_equal 500, status + assert_equal 'Exception!', body + end + + it 'favors subclass handler over superclass handler if available' do + mock_app { + set :raise_errors, false + error(Exception) { 'Exception!' } + error(FooError) { 'FooError!' } + error(RuntimeError) { 'Exception!' } + get '/' do + raise FooError + end + } + + get '/' + assert_equal 500, status + assert_equal 'FooError!', body + end + it "sets env['sinatra.error'] to the rescued exception" do mock_app { set :raise_errors, false