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/dfgdgdgdgfd
I 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/dfgdgdgdgfd
I 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:
def method_missing(m, *args, &block)
Rails.logger.error(m)
redirect_to :controller=>"errors", :action=>"error_404"
# or render/redirect_to somewhere else
end
and then you have to combine it with this code:
unless Rails.application.config.consider_all_requests_local
rescue_from Exception, :with => :method_missing
rescue_from ActiveRecord::RecordNotFound, :with => :method_missing
rescue_from AbstractController::ActionNotFound, :with => :method_missing
rescue_from ActionController::RoutingError, :with => :method_missing
rescue_from ActionController::UnknownController, :with => :method_missing
rescue_from ActionController::UnknownAction, :with => :method_missing
end
精彩评论