This is bugging me just because it seems like it shouldn't be that hard to debug but I cannot figure out what is going on.
We have a 404 page at <app_root>/public/404.html.erb
We then have some custom logic for handling 404s in our application controller
def render_404
if request.format.json?
render({
json: {message: "Not found: /#{params[:path]}"},
status: :not_found
})
else
@fail_photo = Photo.find_by(name: "programmatic_404_image")
render({
file: Rails.root.join("public", "404.html.erb"),
layout: false,
status: :not_found
})
end
end
This works in production but in development it wraps the whole thing in a <pre>
tag and renders the html as raw text. I can fix this by changing to layout: true
and removing the .erb
extension from the file. Obviously the erb is no longer processed but it now serves everything else.
I've looked throuhg the environment files in config for settings that could be affecting this but haven't come up with anything. Any thoughts?
CodePudding user response:
Don't put your erb templates in /public
to begin with. The only reason Rails places the default error pages there is that the default error handler just redirects to a static file. There is no reason you should ever put anything that cannot be served straight by the web server (apache, nginx) in the /public
directory.
You also want to to be careful what you toss into your application controller as you're putting that code into every controller in your application.
Instead create a seperate controller and just place your views like you normally would (app/views/errors):
class ErrorsController < ApplicationController
def not_found
respond_to do |format|
format.json { head :not_found }
format.html { render "404", status: :not_found }
end
end
end
Rails.application.routes.draw do
...
match "/404", to: "errors#not_found", via: :all
...
end
module YourAppName
class Application < Rails::Application
# ...
config.exceptions_app = self.routes # Add this line
end
end
The handling of error pages is controlled by config.consider_all_requests_local
. In development it defaults to true and displays those helpful error pages for debugging so you need to set it to false
in config/environments/development.rb
to actually see your custom error pages.
CodePudding user response:
Public directory expects static pages to be put, some thing which is interacting the ruby code should not be there. You can make a Error controller, I do not get the use of
@fail_photo = Photo.find_by(name: "programmatic_404_image")
If you want to show it in view, you can redirect to a page where 404 image will be hard-coded. Better to put this image either in public or any s3 bucket, and serve it from there. No need to put in a DB with url. At least we should not request DB for serving a single image.