Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

286 lines (247 sloc) 7.363 kb
require File.expand_path('../helper', __FILE__)
class FooError < RuntimeError
end
class FooNotFound < Sinatra::NotFound
end
class FooSpecialError < RuntimeError
def http_status; 501 end
end
class FooStatusOutOfRangeError < RuntimeError
def code; 4000 end
end
class FooWithCode < RuntimeError
def code; 419 end
end
class FirstError < RuntimeError; end
class SecondError < RuntimeError; end
class MappedErrorTest < Test::Unit::TestCase
def test_default
assert true
end
describe 'Exception Mappings' do
it 'invokes handlers registered with ::error when raised' do
mock_app do
set :raise_errors, false
error(FooError) { 'Foo!' }
get('/') { raise FooError }
end
get '/'
assert_equal 500, status
assert_equal 'Foo!', body
end
it 'passes the exception object to the error handler' do
mock_app do
set :raise_errors, false
error(FooError) { |e| assert_equal(FooError, e.class) }
get('/') { raise FooError }
end
get('/')
end
it 'uses the Exception handler if no matching handler found' do
mock_app do
set :raise_errors, false
error(Exception) { 'Exception!' }
get('/') { raise FooError }
end
get '/'
assert_equal 500, status
assert_equal 'Exception!', body
end
it 'walks down inheritance chain for errors' do
mock_app do
set :raise_errors, false
error(RuntimeError) { 'Exception!' }
get('/') { 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 do
set :raise_errors, false
error(Exception) { 'Exception!' }
error(FooError) { 'FooError!' }
error(RuntimeError) { 'Exception!' }
get('/') { 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 do
set :raise_errors, false
error(FooError) do
assert env.include?('sinatra.error')
assert env['sinatra.error'].kind_of?(FooError)
'looks good'
end
get('/') { raise FooError }
end
get '/'
assert_equal 'looks good', body
end
it "raises errors from the app when raise_errors set and no handler defined" do
mock_app do
set :raise_errors, true
get('/') { raise FooError }
end
assert_raise(FooError) { get '/' }
end
it "calls error handlers before raising errors even when raise_errors is set" do
mock_app do
set :raise_errors, true
error(FooError) { "she's there." }
get('/') { raise FooError }
end
assert_nothing_raised { get '/' }
assert_equal 500, status
end
it "never raises Sinatra::NotFound beyond the application" do
mock_app(Sinatra::Application) do
get('/') { raise Sinatra::NotFound }
end
assert_nothing_raised { get '/' }
assert_equal 404, status
end
it "cascades for subclasses of Sinatra::NotFound" do
mock_app do
set :raise_errors, true
error(FooNotFound) { "foo! not found." }
get('/') { raise FooNotFound }
end
assert_nothing_raised { get '/' }
assert_equal 404, status
assert_equal 'foo! not found.', body
end
it 'has a not_found method for backwards compatibility' do
mock_app { not_found { "Lost, are we?" } }
get '/test'
assert_equal 404, status
assert_equal "Lost, are we?", body
end
it 'inherits error mappings from base class' do
base = Class.new(Sinatra::Base)
base.error(FooError) { 'base class' }
mock_app(base) do
set :raise_errors, false
get('/') { raise FooError }
end
get '/'
assert_equal 'base class', body
end
it 'overrides error mappings in base class' do
base = Class.new(Sinatra::Base)
base.error(FooError) { 'base class' }
mock_app(base) do
set :raise_errors, false
error(FooError) { 'subclass' }
get('/') { raise FooError }
end
get '/'
assert_equal 'subclass', body
end
it 'honors Exception#http_status if present' do
mock_app do
set :raise_errors, false
error(501) { 'Foo!' }
get('/') { raise FooSpecialError }
end
get '/'
assert_equal 501, status
assert_equal 'Foo!', body
end
it 'does not use Exception#code by default' do
mock_app do
set :raise_errors, false
get('/') { raise FooWithCode }
end
get '/'
assert_equal 500, status
end
it 'uses Exception#code if use_code is enabled' do
mock_app do
set :raise_errors, false
set :use_code, true
get('/') { raise FooWithCode }
end
get '/'
assert_equal 419, status
end
it 'does not rely on Exception#code for invalid codes' do
mock_app do
set :raise_errors, false
set :use_code, true
get('/') { raise FooStatusOutOfRangeError }
end
get '/'
assert_equal 500, status
end
it "allows a stack of exception_handlers" do
mock_app do
set :raise_errors, false
error(FirstError) { 'First!' }
error(SecondError) { 'Second!' }
get('/'){ raise SecondError }
end
get '/'
assert_equal 500, status
assert_equal 'Second!', body
end
it "allows an exception handler to pass control to the next exception handler" do
mock_app do
set :raise_errors, false
error(500, FirstError) { 'First!' }
error(500, SecondError) { pass }
get('/') { raise 500 }
end
get '/'
assert_equal 500, status
assert_equal 'First!', body
end
it "allows an exception handler to handle the exception" do
mock_app do
set :raise_errors, false
error(500, FirstError) { 'First!' }
error(500, SecondError) { 'Second!' }
get('/') { raise 500 }
end
get '/'
assert_equal 500, status
assert_equal 'Second!', body
end
end
describe 'Custom Error Pages' do
it 'allows numeric status code mappings to be registered with ::error' do
mock_app do
set :raise_errors, false
error(500) { 'Foo!' }
get('/') { [500, {}, 'Internal Foo Error'] }
end
get '/'
assert_equal 500, status
assert_equal 'Foo!', body
end
it 'allows ranges of status code mappings to be registered with :error' do
mock_app do
set :raise_errors, false
error(500..550) { "Error: #{response.status}" }
get('/') { [507, {}, 'A very special error'] }
end
get '/'
assert_equal 507, status
assert_equal 'Error: 507', body
end
it 'allows passing more than one range' do
mock_app do
set :raise_errors, false
error(409..411, 503..509) { "Error: #{response.status}" }
get('/') { [507, {}, 'A very special error'] }
end
get '/'
assert_equal 507, status
assert_equal 'Error: 507', body
end
end
end
Jump to Line
Something went wrong with that request. Please try again.