- Suppose we decide to catch access to a forbidden part of our application by raising and rescuing AreaAccessDenied exception.
- For this, we can subclass StandardError to create a custom error that can be handled using rescue_action. Looks like only classes subclassing from StandardError get handled using rescue. Add the following line in a separate file or perhaps in application.rb if you don't mind living with it.
class AreaAccessDenied subclass StandardError; end
(replace subclass with a 'smaller than' symbol before use) - We need to handle those exceptions for which we want to show the user some output, in rescue_action_in_public.
- Edit config/development.rb to mark all requests non-local. This is necessary for rescue_action_in_public to catch exceptions in development mode. (for a clear idea, look at rescue_action code; all non-local requests are sent to rescue_action_in_public and others are sent to rescue_action_locally). (Do NOT FORGET to restart your development server for the environment settings to take effect!) config.action_controller.consider_all_requests_local = false #true
- Edit application.rb (Notice the double-colon prefix in ActionController in RoutingError and UnknownAction)
def rescue_action_in_public(e)
case e
when ActiveRecord::RecordNotFound, ::ActionController::RoutingError, ::ActionController::UnknownAction
logger.error "Exception: #{e.class}: #{e.message}" render :text => "Ooops!"
when AreaAccessDenied
logger.error "Exception: #{e.class}: #{e.message}" head :forbidden # status 403
else logger.error "Exception: #{e.class}: #{e.message}" render :file => "#{RAILS_ROOT}/public/500.html", :status => 500
end
end - Using the above method alone doesn't cut it in development mode. We also need to redefine local_request in application.rb to always return false. This is because rescue_action decides based on the return value of method local_request? whether to handle the exception using rescue_action_in_public or rescue_action_locally. controllers/application.rb
def local_request?
false
end - I did not see 'uninitialized constant ActionWebService::Dispatcher::ActionController::RoutingError'. (what are you talking about?). But routing errors were not getting caught through my rescue_action_in_public method without a double-colon.
Sunday, December 2, 2007
Raising and Handling Custom Exceptions in Ruby on Rails
Subscribe to:
Post Comments (Atom)
1 comments:
You Rock! So should I say you Guitarate! :)
Post a Comment