我做了一个简单的应用程序,我想测试页面的404,500等http错误。我已经改变了配置。在我的环境/开发中,将consideration all_requests_local设置为false。但是我仍然有一些问题,所以我想问你几个问题……
-
如果我在浏览器中输入一些不合适的东西,比如
http://localhost:3000/products/dfgdgdgdgfd
,我仍然会看到旧的"未知操作"网站。但是,如果我输入计算机的本地ip地址,例如http://192.168.1.106:3000/products/dfgdgdgdgfd
,我可以看到公共文件夹中的404错误页面。为什么会这样呢? -
我知道,如果我在某个地方部署我的小项目,我的应用程序将使用生产模式,如果发生任何错误,404或500页将显示。但是,如果我想使这些错误页面更加动态(例如,在使用热门产品列表的布局时呈现错误消息),或者只是将它们重定向到主页,该怎么办呢?
2.1。我发现的第一个解决方案是在应用程序控制器中使用rescue_from方法:
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
…但这个代码在任何情况下都不起作用。
2.2。第二个解决方案是将match "*path" , :to => "products#show", :id=>1
(这是我愚蠢的应用程序中的示例主页)或match "*path" , :to => "errors#error_404", :id=>1
放在路线的末尾。rb文件。这段代码只适用于像http://192.168.1.106:3000/dfgdgdgdgfd
这样的错别字,因为如果我尝试http://192.168.1.106:3000/products/dfgdgdgdgfd
(控制器存在,但没有找到动作),我仍然得到404页。我玩了一点尝试像match "*path/*act" , :to => "products#show", :id=>1
或match ":controller(/*act)" , :to => "products#show", :id=>8
,但也没有工作…
2.3。第三个解决方案是在初始化器文件夹中创建一个错误控制器和一个文件,代码如下:
# 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
这是非常有用的,因为它可以让我渲染动态动词文件,但是…它没有渲染任何布局。我试图将body = template.render(:file => file)
更改为body = template.render(:partial => file, :layout => "layouts/application")
,但这只会导致错误。
我知道我做错了什么,我相信这些错误页面有一个有效的解决方案,所以我希望你能帮助…
欢呼。
在你的应用程序控制器中,你需要重写这个方法:
def method_missing(m, *args, &block)
Rails.logger.error(m)
redirect_to :controller=>"errors", :action=>"error_404"
# or render/redirect_to somewhere else
end
,然后你必须把它和下面的代码结合起来:
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