2

我做了一个简单的应用程序,我想测试页面404,500等HTTP错误。我已经改变了config.consider_all_requests_local假我enviroments/development.rb但我仍然有一些问题,所以我想请教您几个问题...Rails,开发环境和错误页面

  1. 如果我在库巴型像http://localhost:3000/products/dfgdgdgdgfd这样的不适当的东西我仍然看到旧的“未知动作”网站。但是,如果我输入我的电脑的本地IP地址为前。 http://192.168.1.106:3000/products/dfgdgdgdgfd我可以从公用文件夹中看到404错误页面。为什么会发生?

  2. 我知道,如果我的地方部署我的小项目比我的应用程序将使用生产模式,如果任何错误会occure的404或500页会显示出来。但是如果我想让这些错误页面更具动态性(例如,在使用具有热门产品列表的布局时呈现错误消息),或者只是将它们重定向到主页面呢?

2.1。我发现的第一个解决方案是使用rescue_from方法在应用控制器:

unless Rails.application.config.consider_all_requests_local 
    rescue_from Exception, :with => :render_error 
    rescue_from ActiveRecord::RecordNotFound, :with => :render_not_found 
    rescue_from AbstractController::ActionNotFound, :with => :render_not_found 
    rescue_from ActionController::RoutingError, :with => :render_not_found 
    rescue_from ActionController::UnknownController, :with => :render_not_found 
    rescue_from ActionController::UnknownAction, :with => :render_not_found 
end 
. 
. 
. 
private 
def render_error exception 
    Rails.logger.error(exception) 
    redirect_to root_path 
    #or 
    # render :controller=>'errors', :action=>'error_500', :status=>500 
end 

def render_not_found exception 
    Rails.logger.error(exception) 
    redirect_to root_path 
    #or 
    # render :controller=>'errors', :action=>'error_404', :status=>404 
end 

...但这些代码并没有在任何情况下工作。

2.2。第二个解决方案是在routes.rb文件的末尾放置match "*path" , :to => "products#show", :id=>1(这是我愚蠢的应用中的示例主页)或match "*path" , :to => "errors#error_404", :id=>1。该代码只适用于像http://192.168.1.106:3000/dfgdgdgdgfd这样的拼写错误,因为如果我尝试http://192.168.1.106:3000/products/dfgdgdgdgfd(控制器存在但操作未找到),我仍然有404页面。 我玩过一些尝试......如match "*path/*act" , :to => "products#show", :id=>1match ":controller(/*act)" , :to => "products#show", :id=>8但这也没有工作...

2.3。第三种解决方案是使控制器错误和初始化文件与此代码文件夹:

# initializers/error_pages.rb 
module ActionDispatch 
    class ShowExceptions 
    protected  
    def rescue_action_in_public(exception) 
     status = status_code(exception).to_s 
     template = ActionView::Base.new(["#{Rails.root}/app/views"]) 
     if ["404"].include?(status) 
     file = "/errors/404.html.erb" 
     else 
     file = "/errors/500.html.erb" 
     end   
     body = template.render(:file => file) 
     render(status, body) 
    end 
    end 
end 

这是非常有用的,因为这将让我来渲染动态ERB文件,但..它没有渲染布局。我试图将body = template.render(:file => file)更改为body = template.render(:partial => file, :layout => "layouts/application"),但它只是出现错误。

我知道我做某事错的,我相信有这些错误页面一个可行的解决方案,所以我希望你能帮助...

干杯。

回答

5

在你的应用程序控制器,你需要重写这个方法:

def method_missing(m, *args, &block) 
    Rails.logger.error(m) 
    redirect_to :controller=>"errors", :action=>"error_404" 
    # or render/redirect_to somewhere else 
end 

,然后你必须把它与此代码相结合:

unless Rails.application.config.consider_all_requests_local 
    rescue_from Exception, :with => :method_missing 
    rescue_from ActiveRecord::RecordNotFound, :with => :method_missing 
    rescue_from AbstractController::ActionNotFound, :with => :method_missing 
    rescue_from ActionController::RoutingError, :with => :method_missing 
    rescue_from ActionController::UnknownController, :with => :method_missing 
    rescue_from ActionController::UnknownAction, :with => :method_missing 
end