2011-03-16 39 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关闭阿帕奇乘客出现错误。

相关问题