1. Suppose we decide to catch access to a forbidden part of our application by raising and rescuing AreaAccessDenied exception.
  2. 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)
  3. We need to handle those exceptions for which we want to show the user some output, in rescue_action_in_public.
  4. 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
  5. 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
  6. 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
  7. 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.