I’ve made a simple app and I wanted to test pages for 404, 500 etc. http errors. I’ve changed config.consider_all_requests_local to false in my enviroments/development.rb but I’ve still got some problems so I would like to ask you a few questions…
-
If I type in my bowser something inappropriate like
http://localhost:3000/products/dfgdgdgdgfdI still see the old “Unknown action” site. However if I type local ip adress of my computer for ex.http://192.168.1.106:3000/products/dfgdgdgdgfdI can see the 404 error page from public folder. Why is that happening? -
I know that if I deploy my little project somewhere than my app will use the production mode and if any error would occure the 404 or 500 page will show up. But what if I want to make those error pages more dynamic ( for ex. rendering error message while using a layout with a list of popular products) or simply redirecting them to the main page?
2.1. The first solution that I found was to use rescue_from method in 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
.
.
.
private
def render_error exception
Rails.logger.error(exception)
redirect_to root_path
#or
# render :controller=>'errors', :action=>'error_500', :status=>500
end
def render_not_found exception
Rails.logger.error(exception)
redirect_to root_path
#or
# render :controller=>'errors', :action=>'error_404', :status=>404
end
… but that code didn’t work at any case.
2.2. The second solution was to place match "*path" , :to => "products#show", :id=>1 (that’s the example main page in my silly app) or match "*path" , :to => "errors#error_404", :id=>1 at the end of the routes.rb file. That code works only for typos like http://192.168.1.106:3000/dfgdgdgdgfd because if I try http://192.168.1.106:3000/products/dfgdgdgdgfd (the controller exists but the action is not found) I still got the 404 page.
I’ve played a bit trying sth like match "*path/*act" , :to => "products#show", :id=>1 or match ":controller(/*act)" , :to => "products#show", :id=>8 but that didn’t work either…
2.3. The third solution was to make controller for errors and a file in initializers folder with this code:
# initializers/error_pages.rb
module ActionDispatch
class ShowExceptions
protected
def rescue_action_in_public(exception)
status = status_code(exception).to_s
template = ActionView::Base.new(["#{Rails.root}/app/views"])
if ["404"].include?(status)
file = "/errors/404.html.erb"
else
file = "/errors/500.html.erb"
end
body = template.render(:file => file)
render(status, body)
end
end
end
That was quite useful because it would let me to render dynamic erb files but.. it’s not rendering any layout. I’ve tried to change body = template.render(:file => file) to body = template.render(:partial => file, :layout => "layouts/application") but it was only cousing errors.
I know that I’m doing sth wrong and I belive that there is a working solution for those error pages so I hope that you can help…
Cheers.
In your application controller you need to override this method:
and then you have to combine it with this code: