开发者

Rails, development env and error pages

开发者 https://www.devze.com 2023-03-03 23:17 出处:网络
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 pr

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...

  1. 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?

  2. 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
0

精彩评论

暂无评论...
验证码 换一张
取 消