When going to on object's show page with an id that doesn't exist, the RecordNotFonud exception is thown. Is there a way I can redirect to some error page, or maybe a different action when this error is thrown?
6 Answers
You may use rescue_from if you are using Rails 3:
class ApplicationController < ActionController::Base rescue_from ActiveRecord::RecordNotFound, :with => :render_404 def render_404 respond_to do |format| format.html { render :action => "errors/404.html.erb", :status => 404 } # and so on.. end end end Yes, you can also do a redirect instead of render, but this is not a good idea. Any semi-automatic interaction with your site will think that the transfer was successfull (because the returned code was not 404), but the received resource was not the one your client wanted.
Comments
See http://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html. Rails has nice features for exception handling.
Comments
I generally do something like this in my ApplicationController
class ApplicationController < ActionController::Base rescue_from ActiveRecord::RecordNotFound, :with => :routing_error private def routing_error redirect_to(root_url, :alert => "Sorry, the page you requested could not be found.") end end Comments
If you need to handle more than one specific exception, use rescue_action or rescue_action_in_public, the difference in to hook local requests or not (development/production in common). I prefer to use in_public , because need to review exception's backtrace in development mode.
take a look at my source code:
class ApplicationController < ActionController::Base include CustomExceptionsHandler .... end module CustomExceptionsHandler # Redirect to login/dashboard path when Exception is caught def rescue_action_in_public(exception) logger.error("\n !!! Exception !!! \n #{exception.message} \n") case exception.class.to_s when "Task::AccessDenied" logger.error(" !!! 403 !!!") notify_hoptoad(exception) //catch this kind of notification to Hoptoad render_403 when "AuthenticatedSystem::PermissionDenied" logger.error(" !!! 403 !!!") render_403 when "Task::MissingDenied" logger.error(" !!! 404 !!!") notify_hoptoad(exception) render_404 when "ActionController::RoutingError" logger.error(" !!! 404 !!!") render_404 else notify_hoptoad(exception) redirect_to(current_user.nil? ? login_path : dashboard_path) and return false end end private #403 Forbidden def render_403 respond_to do |format| format.html { render :template => "common/403", :layout => false, :status => 403 } format.xml { head 403 } format.js { head 403 } format.json { head 403 } end return false end #404 Not Found def render_404 respond_to do |format| format.html { render :template => "common/404", :layout => false, :status => 404 } format.xml { head 404 } format.js { head 404 } format.json { head 404 } end return false end end
rescue .. render :action => 'not_found', :status => 404)