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