Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Internal server error 500 on missing image file (Rails 3.2.12)

If we request a bogus image file, Rails generates an internal 500 server error instead of a 404. See the log below.

Here is the line in routes.rb that catches 404s:

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

Other unknown URLs are handled correctly with 404s. What is different for image files and URLs with file extensions?

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"
like image 526
Crashalot Avatar asked Mar 08 '13 19:03

Crashalot


1 Answers

The problem is that the error_404 method inside the Default controller can't handle requests in png format. When you ask for say, a JSON response, you could build an URL similar to:

/controller/action.json

And inside the action you would have something like

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

As you can see, it's specified how to handle a JSON and an XML request, but since there's no format.png, the action can't handle the .png format. Add this:

format.png # Handle the request here...

Hope it helps :)

Edit

Add this to redirect to your 404 handler:

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

Cheers :)

Edit2

Use this code to catch all kinds of requests:

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

Replace :not_found_view with your 404 page. This will render the 404 page for html requests, and redirect to self (with html format) for any other kind of request.

Hope it helps :)

like image 84
sergelerator Avatar answered Sep 19 '22 16:09

sergelerator