Open ericgj opened 12 years ago
This is a somewhat complex topic, to begin with there is a distinction between
The app-level error handling (1) is well-documented here. Here's the method for defining an error handler:
# Define a custom error handler. Optionally takes either an Exception
# class, or an HTTP status code to specify which errors should be
# handled.
def error(*codes, &block)
args = compile! "ERROR", //, block
codes = codes.map { |c| Array(c) }.flatten
codes << Exception if codes.empty?
codes.each { |c| @errors[c] = args }
end
It's interesting that error handlers are defined as a special kind of route. Anyone want to take a stab at exegesis ?
As for framework-level error handling (2), the relevant code is here (called from the rescue Exception
in dispatch!
):
# Error handling during requests.
def handle_exception!(boom)
@env['sinatra.error'] = boom
status boom.respond_to?(:code) ? Integer(boom.code) : 500
if server_error?
dump_errors! boom if settings.dump_errors?
raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler
end
if not_found?
headers['X-Cascade'] = 'pass'
body '<h1>Not Found</h1>'
end
res = error_block!(boom.class, boom) || error_block!(status, boom)
return res if res or not server_error?
raise boom if settings.raise_errors? or settings.show_exceptions?
error_block! Exception, boom
end
# Find an custom error block for the key(s) specified.
def error_block!(key, *block_params)
base = settings
while base.respond_to?(:errors)
next base = base.superclass unless args = base.errors[key]
args += [block_params]
return process_route(*args)
end
return false unless key.respond_to? :superclass and key.superclass < Exception
error_block!(key.superclass, *block_params)
end
def dump_errors!(boom)
msg = ["#{boom.class} - #{boom.message}:", *boom.backtrace].join("\n\t")
@env['rack.errors'].puts(msg)
end
@codereading/readers