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?
问题:
回答1:
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.
回答2:
In development mode you'll see the exception details but it should automatically render the 404.html file from your public directory when your app is running in production mode.
回答3:
See http://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html. Rails has nice features for exception handling.
回答4:
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
回答5:
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
回答6:
Use a begin - rescue - end construct to catch the exception and do something useful with it.
userid=2 begin u=User.find userid rescue RecordNotFound redirect_to "/errorpage" #Go to erropage if you didn't find the record exit end redirect_to u # Go to the user page