问题
Is there are way to tell Rails to render your custom error pages (for example, the ones you write in your ErrorsController
)? I've searched many topics, and the one that seems to kinda work was to add to your ApplicationController
something like
if Rails.env.production?
rescue_from Exception, :with => :render_error
rescue_from ActiveRecord::RecordNotFound, :with => :render_not_found
rescue_from ActionController::UnknownController, :with => :render_not_found
rescue_from ActionController::UnknownAction, :with => :render_not_found
end
and then you write your methods render_error
and render_not_found
the way you want. This seems to me like a really unelegant solution. Also, it's bad, because you have to know exactly what are all the errors that could happen. It's a temporary solution.
Also, there is really no easy way to rescue an ActionController::RoutingError
that way. I saw that one way was to add something like
get "*not_found", :to => "errors#not_found"
to your routes.rb
. But what if you want to raise somewhere an ActionController::RoutingError
manually? For example, if a person who is not an administrator tries to go to "adminy" controllers by guessing the URL. In those situations I prefer raising a 404 more than raising an "unauthorized access" error of some kind, because that would actually tell the person that he guessed the URL. If you raise it manually, it will try to render a 500 page, and I want a 404.
So is there a way to tell Rails: "In all cases you would normally render a 404.html
or a 500.html
, render my custom 404 and 500 pages"? (Of course, I deleted the 404.html
and 500.html
pages from the public
folder.)
回答1:
Unfortunately there aren't any methods I know of that can be overridden to provide what you want. You could use an around filter. Your code would look something like this:
class ApplicationController < ActionController::Base
around_filter :catch_exceptions
protected
def catch_exceptions
yield
rescue => exception
if exception.is_a?(ActiveRecord::RecordNotFound)
render_page_not_found
else
render_error
end
end
end
You can handle each error as you see fit in that method. Then your #render_page_not_found
and #render_error
methods would have to be something like
render :template => 'errors/404'
You would then need to have a file at app/views/errors/404.html.[haml|erb]
来源:https://stackoverflow.com/questions/9239803/how-to-properly-render-custom-404-and-500-pages