mirror of
https://github.com/sinatra/sinatra
synced 2023-03-27 23:18:01 -04:00
make raise_errors option more reliable
The raise_errors option was implemented as part of the default error handler making it worthless in development mode or with a custom error handler. This moves the implementation to the core dispatch method. While here, clean up the Error class a bit, making it use the options provided and pass the correct HTTP status code.
This commit is contained in:
parent
26facecebf
commit
3105f21132
2 changed files with 36 additions and 11 deletions
|
@ -62,8 +62,12 @@ module Sinatra
|
|||
|
||||
VERSION = '0.3.0'
|
||||
|
||||
class NotFound < RuntimeError; end
|
||||
class ServerError < RuntimeError; end
|
||||
class NotFound < RuntimeError
|
||||
def self.code ; 404 ; end
|
||||
end
|
||||
class ServerError < RuntimeError
|
||||
def self.code ; 500 ; end
|
||||
end
|
||||
|
||||
Result = Struct.new(:block, :params, :status) unless defined?(Result)
|
||||
|
||||
|
@ -171,14 +175,24 @@ module Sinatra
|
|||
|
||||
class Error
|
||||
|
||||
attr_reader :code, :block
|
||||
attr_reader :type, :block, :options
|
||||
|
||||
def initialize(code, &b)
|
||||
@code, @block = code, b
|
||||
def initialize(type, options={}, &block)
|
||||
@type = type
|
||||
@block = block
|
||||
@options = options
|
||||
end
|
||||
|
||||
def invoke(request)
|
||||
Result.new(block, {}, 404)
|
||||
Result.new(block, options, code)
|
||||
end
|
||||
|
||||
def code
|
||||
if type.respond_to?(:code)
|
||||
type.code
|
||||
else
|
||||
500
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1083,7 +1097,7 @@ module Sinatra
|
|||
# The Sinatra::ServerError handler is used by default when an exception
|
||||
# occurs and no matching error handler is found.
|
||||
def error(type=ServerError, options = {}, &b)
|
||||
errors[type] = Error.new(type, &b)
|
||||
errors[type] = Error.new(type, options, &b)
|
||||
end
|
||||
|
||||
# Define a custom error handler for '404 Not Found' responses. This is a
|
||||
|
@ -1229,6 +1243,7 @@ module Sinatra
|
|||
rescue => e
|
||||
request.env['sinatra.error'] = e
|
||||
context.status(500)
|
||||
raise if options.raise_errors && e.class != NotFound
|
||||
result = (errors[e.class] || errors[ServerError]).invoke(request)
|
||||
returned =
|
||||
catch(:halt) do
|
||||
|
@ -1250,7 +1265,6 @@ module Sinatra
|
|||
events[:get] << Static.new
|
||||
configure do
|
||||
error do
|
||||
raise request.env['sinatra.error'] if Sinatra.options.raise_errors
|
||||
'<h1>Internal Server Error</h1>'
|
||||
end
|
||||
not_found { '<h1>Not Found</h1>'}
|
||||
|
|
|
@ -6,6 +6,7 @@ context "Mapped errors" do
|
|||
|
||||
setup do
|
||||
Sinatra.application = nil
|
||||
Sinatra.application.options.raise_errors = false
|
||||
end
|
||||
|
||||
specify "are rescued and run in context" do
|
||||
|
@ -15,7 +16,7 @@ context "Mapped errors" do
|
|||
end
|
||||
|
||||
get '/' do
|
||||
raise FooError.new
|
||||
raise FooError
|
||||
end
|
||||
|
||||
get_it '/'
|
||||
|
@ -32,7 +33,7 @@ context "Mapped errors" do
|
|||
end
|
||||
|
||||
get '/' do
|
||||
raise FooError.new
|
||||
raise FooError
|
||||
end
|
||||
|
||||
get_it '/'
|
||||
|
@ -49,7 +50,7 @@ context "Mapped errors" do
|
|||
end
|
||||
|
||||
get '/' do
|
||||
raise FooError.new
|
||||
raise FooError
|
||||
end
|
||||
|
||||
get_it '/'
|
||||
|
@ -58,4 +59,14 @@ context "Mapped errors" do
|
|||
|
||||
end
|
||||
|
||||
specify "raises errors when the raise_errors option is set" do
|
||||
Sinatra.application.options.raise_errors = true
|
||||
error FooError do
|
||||
end
|
||||
get '/' do
|
||||
raise FooError
|
||||
end
|
||||
assert_raises(FooError) { get_it('/') }
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue