Module: Strelka::App::Errors
Overview
Custom error-handling plugin for Strelka::App.
plugin :errors
# Handle only status 400 errors
on_status HTTP::BAD_REQUEST do |res, status_info|
# Do something on 400 errors
end
# Handle any other error in the 4xx range
on_status 400..499 do |res, status_info|
# Do something on 4xx errors
end
If you have the :templating plugin loaded, you can substitute a Symbol that corresponds with one of the declared templates instead:
class MyApp < Strelka::App
plugins :errors, :templating
layout 'layout.tmpl'
templates :missing => 'errors/missing.tmpl'
# Load the 'missing' template, wrap it up in the layout
# template and render that as the body of the 404
# response
on_status HTTP::NOT_FOUND, :missing
end # class MyApp
The template can access the status info hash via the :status_info note
on the request or response object:
Sorry, there was a error:
<?escape request.notes[:status_info][:message] ?>.
If you want to do something application-specific for an error, but still use the default error-handling, just call finish_with again with the status info from your status handler:
class MyApp < Strelka::App
plugins :errors
# Send an email when an app is going to return a 500 error
on_status HTTP::SERVER_ERROR do |res, info|
require 'mail'
Mail.deliver do
from '[email protected]'
to '[email protected]'
subject "SERVER_ERROR: %p [%s]" %
[ self.class, self.class.version_string ]
body "Server error while running %p [%s]: %s" %
[ self.class, self.conn, status. ]
end
# Finish the transaction
finish_with( info )
end
def handle( req )
finish_with( HTTP::SERVER_ERROR, "Ack! Something bad happened." )
end
end # class MyApp
See the documentation for ClassMethods.on_status for more details on the status-handler block.
Defined Under Namespace
Modules: ClassMethods
Constant Summary collapse
- DEFAULT_HANDLER_STATUS_RANGE =
The range of status codes to delegate to an on_status handler that doesn't specify one
400..599
Instance Attribute Summary
Attributes included from Plugin
Instance Method Summary collapse
-
#handle_request(request) ⇒ Object
Check for a status response that is hooked, and run the hook if one is found.
-
#handle_status_response(request, status_info) ⇒ Object
Return a response built out of the
status_infofor the specifiedrequestif there is a custom handler. -
#status_handler_for(status_code) ⇒ Object
Find a status handler for the given
status_codeand return it as an UnboundMethod.
Methods included from Plugin
extended, plugin_name, run_inside, run_outside
Instance Method Details
#handle_request(request) ⇒ Object
Check for a status response that is hooked, and run the hook if one is found.
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/strelka/app/errors.rb', line 144 def handle_request( request ) self.log.debug "[:errors] Wrapping request in custom error-handling." response = nil # Catch a finish_with; the status_response will only be non-nil status_response = catch( :finish ) do # Provide our own exception-handling and translate them into server errors begin response = super rescue => err self.log.error "%s: %s %s" % [ err.class.name, err., err.backtrace.first ] err.backtrace[ 1..-1 ].each {|frame| self.log.debug(' ' + frame) } finish_with( status: HTTP::SERVER_ERROR, message: err., headers: {}, backtrace: err.backtrace, exception: err ) end nil end # If the app or any plugins threw a finish, look for a handler for the status code # and call it if one is found. response = self.handle_status_response( request, status_response ) if status_response return response end |
#handle_status_response(request, status_info) ⇒ Object
Return a response built out of the status_info for the specified request if there
is a custom handler. If there isn't one, rethrows to the main :finish handler.
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/strelka/app/errors.rb', line 179 def handle_status_response( request, status_info ) status = status_info[:status] # If we can't find a custom handler for this status, re-throw # to the default handler instead handler = self.status_handler_for( status ) or throw( :finish, status_info ) self.log.debug "Custom %d handler: %p" % [ status, handler ] # Set up the request's response with the right status code request.notes[:status_info] = status_info response = request.response response.status = status # The handler is an UnboundMethod, so bind it to the app instance # and call it return handler.bind( self ).call( response, status_info ) end |
#status_handler_for(status_code) ⇒ Object
Find a status handler for the given status_code and return it as an UnboundMethod.
200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/strelka/app/errors.rb', line 200 def status_handler_for( status_code ) self.log.debug "[:errors] Looking for a status handler for %d responses" % [ status_code ] handlers = self.class.status_handlers ranges = handlers.keys ranges.each do |range| return handlers[ range ] if range.include?( status_code ) end return nil end |