2011-03-16 14 views
7

Im utilizzando Rails, Passenger (entrambi sono 3.0.5) e Nginx sul mio server di produzione. Come ho sentito, Rails dovrebbe mostrare public/404.html o public/500.html invece di errori di sviluppo come ActiveRecord::RecordNotFound o Unknown action ma ciò non accade. Ho provato a eliminare il file config.ru e ho impostato rack_env o rails_env in nginx.conf ma nulla è stato di aiuto.Rails 3 - errori di sviluppo in modalità produzione

Ecco il mio 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; 
     } 
    } 
} 

Sembra che questa domanda duplica this one ma non ci sono proposte di lavoro.

UPD: Ho entrambe le app di sviluppo e di produzione sullo stesso PC. Nella produzione Rails ignora config.consider_all_requests_local = false (in /config/environments/production.rb) a causa del metodo local_request?. Così una delle possibili soluzioni è elencato di seguito (tratto da 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 

O per Rails 3:

class ActionDispatch::Request 
def local? 
    false 
end 
end 

risposta

2

Spostare il dichiarazione root fino al blocco "server" in modo che il server può utilizzare l'applicazione Rails definito la gestione pagine di errore quando si riceve un errore 5XX, 4XX.

Oppure aggiungi error_page direttive al blocco posizione in cui passeggero è in uso in modo che i gestori di errori in grado di risolvere il public/5xx.html nell'elenco pubblico applicazione Rails quando necessario.

Se l'app non serve la pagina e nginx non ha visibilità sulla pagina statica, non può servire la pagina desiderata.

+0

Sembra quasi al mio problema, ma non ha aiutato. Si prega di consultare nginx.conf aggiornato. – sunki

+0

Hai un file 500.html e 404.html nella directory "pubblica" delle tue guide? – Brandon

+0

Sì, certo ... – sunki

5

per ottenere questo lavoro in Rails 3 dovrete effettuare le seguenti operazioni:

Innanzitutto, crea le tue 404 e 500 pagine di errore. Inserisco il mio in app/views/errors/404.html.erb e app/views/errors/500.html.erb.

In secondo luogo, aggiungere il seguente al 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 

Infine, rendere il vostro production.rb non prendere in considerazione tutte le richieste locali:

config.consider_all_requests_local = false 

PS: Tenete a mente che quando un completo si verifica un errore di routing - ovvero quando non c'è assolutamente alcuna corrispondenza di percorso, non solo un errore di NotRound di ActiveRecord, verrà visualizzato public/404.html, quindi è bene averlo a posto. Solitamente lo reindirizzo al mio errors_controller, il che garantisce che tutti gli errori 404 non rilevati da queste ultime eccezioni siano ancora correttamente reindirizzati a ErrorsController.

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

Questo è un modo per farlo se si desidera che l'app Rails lo gestisca e serva la pagina. Se vuoi che nginx lo gestisca, modifica le tue direttive di blocco.Entrambi funzioneranno, dipende solo da dove si desidera gestire questo tipo di errori. – Brandon

+0

Grazie. Ho visto smth simile [qui] (http://stackoverflow.com/questions/2064503/ruby-on-rails-http-error-handling). Ma questo non è molto vicino al mio problema. Vorrei evitare qualsiasi possibilità di mostrare errori di sviluppo. Un altro modo per farlo, ad esempio, è sovrascrivere il metodo 'render_exception'. La soluzione più nativa è stata già proposta da Brandon. – sunki

+2

Non c'è possibilità di mostrare errori di sviluppo se consider_all_requests_local è false. L'utente riceverà solo una pagina di errore 500 o 404, ma nessuna traccia di stack o messaggio di errore interno. –

3

Per ottenere gli errori solo in alcuni controllori

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

Il passeggero apache ho usato l'opzione di configurazione di Apache PassengerFriendlyErrorPages off.

Problemi correlati