2013-03-08 11 views
5

Se si richiede un file immagine fasullo, Rails genera un errore interno del server 500 anziché un 404. Vedere il registro seguente.Errore interno del server 500 sul file immagine mancante (Rails 3.2.12)

Ecco la linea di routes.rb che cattura 404s:

# Catches all 404 errors and redirects 
match '*url' => 'default#error_404' 

Altri URL sconosciuti vengono gestiti correttamente con 404s. Cosa c'è di diverso per i file di immagini e gli URL con estensioni di file?

Started GET "/images/doesnotexistyo.png" for 71.198.44.101 at 2013-03-08 07:59:24 +0300 
Processing by DefaultController#error_404 as PNG 
    Parameters: {"url"=>"images/doesnotexistyo"} 
Completed 500 Internal Server Error in 1ms 

ActionView::MissingTemplate (Missing template default/error_404, application/error_404 with {:locale=>[:en], :formats=>[:png], :handlers=>[:erb, :builder]}. Searched in: 
    * "/home/prod/Prod/app/views" 

risposta

4

Il problema è che il metodo error_404 all'interno del controller Default non può gestire le richieste in formato png. Quando si chiede per esempio, una risposta JSON, si potrebbe costruire un URL simile a:

/controller/action.json 

E dentro l'azione si avrebbe qualcosa come

def action 
    respond_to do |format| 
    format.html # Renders the default view 
    format.json { render :json => @model } 
    format.xml { render :xml => @model } 
    end 
end 

Come si può vedere, è specificato come gestire un JSON e una richiesta XML, ma poiché non c'è format.png, l'azione non può gestire il formato .png. Aggiungere questo:

format.png # Handle the request here... 

Speranza che aiuta :)

Modifica

aggiungere questo per reindirizzare al 404 gestore:

def error_404 
    respond_to do |format| 
    format.html 
    format.png { redirect_to :controller => 'default', :action => 'error_404' } 
    end 
end 

Saluti :)

Modifica2

Usa questo codice per catturare tutti i tipi di richieste:

def error_404 
    respond_to do |format| 
    format.html { render :not_found_view } 
    format.all { redirect_to controller: 'default', action: 'error_404' } 
    end 
end 

Sostituire :not_found_view con la tua pagina 404. Ciò renderà la pagina 404 per le richieste html e reindirizza a self (con il formato html) per qualsiasi altro tipo di richiesta.

Speranza che aiuta :)

+0

grazie! se non è un formato HTML, possiamo forzarlo a visualizzare la visualizzazione HTML e mostrare la pagina 404 corretta? – Crashalot

+0

Modificata la mia risposta, spero che sia d'aiuto: D – sergelerator

+0

Come possiamo impostare un catch-all? In altre parole, se vogliamo catturare qualsiasi estensione di file (ad es., Jpg, .gif) senza specificarne singolarmente, come ci avvicineremmo? – Crashalot

0

Che cos'è DefaultController? Tale controller a che fare con il 404, invece di risposta predefinita Rails:

ActionController::RoutingError (No route matches [GET] "/images/doesnotexistyo.png"): 

Così scoprire questo controller, error_404 viene eseguita ed è stato trovato nessun modello predefinito/error_404, da qui l'errore 500.

probabilmente hai un codice simile a questo da qualche parte nel codice:

rescue_from ActiveRecord::RecordNotFound, :with => :error_404 
+0

abbiamo aggiornato il q con una linea in percorsi.rb che cattura 404. la domanda è: perché funziona per alcuni URL e non quelli con estensioni di file (immagini in particolare)? – Crashalot

+0

Qual è il contenuto del metodo error_404? Il metodo sta arrivando alla fine e sta tentando di eseguire il rendering di una vista con erb o builder, usando il formato fornito: png. A meno che tu non abbia un errore_404.png.erb o error_404.png.builder vedrai questo errore nel modo in cui l'app è configurata in questo momento. – Leito

+0

ahhh, capisco. qual è il modo giusto per gestire questo (e 404 in generale) in 3.2.12? per rispondere alla tua domanda, error_404 è un'azione vuota che mostra solo la vista .html.erb corrispondente. – Crashalot

0

Forse non per te, ma da quando faccio alcuni controlli finali per le pagine dinamicamente nei miei controllori, mi basta seguire tutta la mia 404'ing con uno a gestire non HTML file:

format.all { render :status => 404, :nothing => true } 
Problemi correlati