- 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.
handle exceptions globally
Archived Posts from this Category
December 3, 2007
Raising and Handling Custom Exceptions in Ruby on Rails
Posted by guitarati under exceptions in ruby on rails, extend StandardError, handle exceptions globally, raise custom exception, rescue_action_in_public, Ruby on Rails1 Comment