How to properly render custom 404 and 500 pages?

霸气de小男生 提交于 2020-01-14 05:09:18

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!