diff --git a/CHANGES b/CHANGES index eb736710..965e5d28 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,9 @@ Moreover, it will be ignored if the value is not between 400 and 599. You should use Exception#http_status instead. (Konstantin Haase) + * Status, headers and body will be set correctly in an after filter when using + halt in a before filter or route. (Konstantin Haase) + = 1.3.2 / 2011-12-30 * Don't automatically add `Rack::CommonLogger` if `Rack::Server` is adding it, diff --git a/lib/sinatra/base.rb b/lib/sinatra/base.rb index 4770ce90..d07a95b7 100644 --- a/lib/sinatra/base.rb +++ b/lib/sinatra/base.rb @@ -877,15 +877,18 @@ module Sinatra elsif res.respond_to? :each body res end + nil # avoid double setting the same response tuple twice end # Dispatch a request with error handling. def dispatch! - static! if settings.static? && (request.get? || request.head?) - filter! :before - route! + invoke do + static! if settings.static? && (request.get? || request.head?) + filter! :before + route! + end rescue ::Exception => boom - handle_exception!(boom) + invoke { handle_exception!(boom) } ensure filter! :after unless env['sinatra.static_file'] end diff --git a/test/routing_test.rb b/test/routing_test.rb index 28541ad9..9b1e49eb 100644 --- a/test/routing_test.rb +++ b/test/routing_test.rb @@ -531,6 +531,17 @@ class RoutingTest < Test::Unit::TestCase assert_equal 'HelloWorldHowAreYou', body end + it 'sets response.status with halt' do + status_was = nil + mock_app do + after { status_was = status } + get('/') { halt 500, 'error' } + end + get '/' + assert_status 500 + assert_equal 500, status_was + end + it "transitions to the next matching route on pass" do mock_app { get '/:foo' do