2011-03-16 38 views
7

在我的生產服務器上使用Rails,Passenger(都是3.0.5)和Nginx。據我所知,Rails應該顯示public/404.htmlpublic/500.html,而不是像ActiveRecord::RecordNotFoundUnknown action這樣的開發錯誤,但這並未發生。我嘗試刪除config.ru文件,並在nginx.conf中設置rack_env或rails_env,但沒有任何幫助。Rails 3 - 生產模式下的開發錯誤

這裏是我的nginx.conf:

worker_processes 1; 

events { 
    worker_connections 1024; 
} 

http { 
    passenger_root /home/makk/.rvm/gems/ruby-1.9.2-p0/gems/passenger-3.0.5; 
    passenger_ruby /home/makk/.rvm/bin/passenger_ruby; 
    #passenger_ruby /home/makk/.rvm/wrappers/ruby-1.9.2-p0/ruby; 

    include  mime.types; 
    default_type application/octet-stream; 

    sendfile  on; 
    keepalive_timeout 65; 

    server { 
     listen  80; 
     server_name localhost; 

     location/{ 
      root /home/makk/projects/1server/deploy/current/public; 
      index index.html index.htm; 
      passenger_enabled on; 
      rack_env production; 

      recursive_error_pages on; 

      if (-f /home/makk/projects/1server/maintenance.html) { 
       return 503; 
      } 

      error_page 404 /404.html; 
      error_page 500 502 504 /500.html; 
      error_page 503 @503; 
     } 

     location @503 { 
      error_page 405 = /maintenance.html; 

      # Serve static assets if found. 
       if (-f $request_filename) { 
       break; 
      } 
      rewrite ^(.*)$ /maintenance.html break; 
     } 

     location ~ ^(\/phpmyadmin\/)(.*)$ { 
     fastcgi_pass 127.0.0.1:9000; 
     fastcgi_index index.php; 
     fastcgi_split_path_info   ^(\/phpmyadmin\/)(.*)$; 
     fastcgi_param SCRIPT_FILENAME /usr/share/phpmyadmin/$fastcgi_path_info; 
     include   fastcgi_params; 
     } 
    } 
} 

看來,這個問題重複this one,但沒有工作的建議。

UPD:我在同一臺PC上都有開發和生產應用程序。在生產中,由於local_request?方法的原因,Rails忽略config.consider_all_requests_local = false(在/config/environments/production.rb中)。所以,可能的解決方案之一如下(從here拍攝):

# config/initializers/local_request_override.rb 
module CustomRescue 
    def local_request? 
    return false if Rails.env.production? || Rails.env.staging? 
    super 
    end 
end 

ActionController::Base.class_eval do 
    include CustomRescue 
end 

或者爲Rails 3:

class ActionDispatch::Request 
def local? 
    false 
end 
end 

回答

2

移動你的root聲明上升到「服務器」塊所以當它收到5XX,4XX錯誤服務器可以使用Rails應用程序定義的錯誤處理頁面。

或將error_page指令添加到乘客正在使用的位置塊,以便錯誤處理程序可以在需要時解決Rails應用程序公共目錄中的public/5xx.html

如果您的應用程序沒有提供頁面,並且nginx對靜態頁面沒有可見性,那麼它無法提供您想要的頁面。

+0

幾乎看我的問題,但沒有幫助。請參閱更新的nginx.conf。 – sunki

+0

你的rails「public」目錄中是否有500.html和404.html? – Brandon

+0

當然可以...... – sunki

5

要獲得Rails 3中這個工作,你就必須做到以下幾點:

首先,創建404和500錯誤頁面。我把它放在app/views/errors/404.html.erbapp/views/errors/500.html.erb

其次,添加以下application_controller.rb:

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 

def render_error exception 
    Rails.logger.error(exception) 
    render :template => "/errors/500.haml", :status => 500 
end 

def render_not_found exception 
    Rails.logger.error(exception) 
    render :template => "/errors/404.haml", :status => 404 
end 

最後,讓你的production.rb不考慮所有請求本地:

config.consider_all_requests_local = false 

PS:請記住,當一個完整的發生路由錯誤 - 即當絕對不存在路由匹配時,不僅僅是ActiveRecord NotFound錯誤,public/404.html將顯示出來,所以最好有適當的路由。我通常只是將它重定向到我的errors_controller,這確保了後面提到的異常沒有捕獲的任何404錯誤仍然被正確地重定向到ErrorsController。

<script type="text/javascript"> 
<!-- 
window.location = "<%= request.host_with_port %>/errors/404" 
//--> 
</script> 
+0

如果您希望Rails應用程序處理它並提供頁面,這是一種方法。如果你想讓nginx處理它,那麼編輯你的block指令。兩者都可以工作,只取決於你想要處理這些類型的錯誤。 – Brandon

+0

謝謝。我見過smth類似[這裏](http://stackoverflow.com/questions/2064503/ruby-on-rails-http-error-handling)。但這並不是很接近我的問題。我想避免任何顯示開發錯誤的可能性。例如,另一種方法是覆蓋'render_exception'方法。 Brandon已經提出了更原生的解決方案。 – sunki

+2

如果consider_all_requests_local爲false,則不會呈現開發錯誤。用戶將得到一個500或404錯誤頁面,但沒有堆棧跟蹤或內部錯誤消息。 –

3

爲僅在某些控制器

class AdminController < ApplicationController 
    rescue_from Exception, :with => :render_simple_error if Rails.env.production? 
    def render_simple_error(e) 
    render :text => "#{e.message} -- #{e.class}<br/>#{e.backtrace.join("<br/>")}" 
    end 
end 
1

在我使用的Apache配置選項 PassengerFriendlyErrorPages關閉阿帕奇乘客出現錯誤。

相關問題