Рельсы 3-ошибки разработки в производственном режиме


Я использую Rails, Passenger (оба 3.0.5) и Nginx на моем производственном сервере. Как я слышал, Rails должны показывать public/404.html или public/500.html вместо ошибок разработки, таких как ActiveRecord::RecordNotFound или Unknown action, но этого не происходит. Я пытался удалить файл config.ru и установить rack_env или rails_env в nginx.conf, но ничего не помогало.

Вот мой 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;
        }
    }
}

Кажется, что этот вопрос дублируетЭтот , но рабочих предложений нет.

UPD : у меня есть как разработка, так и производство приложений на одном компьютере. In production Rails игнорирует config.consider_all_requests_local = false (in / config / environments / production.rb) за счет метода local_request?. Итак, одно из возможных решений приведено ниже (взято из здесь):

# 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

Или для рельсов 3:

class ActionDispatch::Request
 def local?
   false
 end
end
4 7

4 ответа:

Переместите объявление root в блок "сервер", чтобы сервер мог использовать страницы обработки ошибок, определенные приложением Rails, когда он получает ошибку 5XX, 4XX.

Или добавьте Директивы error_page в блок location, где используется passenger, чтобы обработчики ошибок могли при необходимости разрешить public/5xx.html В общем каталоге приложения Rails.

Если ваше приложение не обслуживает страницу и у nginx нет видимости статической страницы, то оно не может обслуживать нужную вам страницу.

Чтобы заставить это работать в Rails 3, вам придется сделать следующее:

Сначала создайте свои 404 и 500 страниц ошибок. Я положил свой в app/views/errors/404.html.erb и app/views/errors/500.html.erb.

Во-вторых, добавьте в application_controller следующее.РБ:

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

Наконец, сделайте свою продукцию.РБ не считает все запросы локальными:

config.consider_all_requests_local = false

P. S: имейте в виду, что когда происходит полная ошибка маршрутизации, то есть когда нет абсолютно никакого совпадения маршрута, а не только ошибка ActiveRecord NotFound, public/404.формат html будет отображаться, так что это хорошо, чтобы иметь это на месте. Обычно я просто перенаправляю его на свой errors_controller, что гарантирует, что любые 404 ошибки, не пойманные последними упомянутыми исключениями, все еще правильно перенаправляются на ErrorsController.

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

Получать ошибки только в определенных контроллерах

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

На Apache passenger я использовал опцию конфигурации apache PassengerFriendlyErrorPages выкл.