我们有一个基本上在生产中默默失败的操作,因为它引发了ActiveRecord::RecordNotFound
错误,Rails将其视为404错误而不是500错误 - 这意味着它不会被我们捕获错误记录器。
我不喜欢Rails将某些错误映射到404s-我认为应由开发人员决定URL是否无效,或者检索记录失败是否是应用程序错误。
我们如何确保将所有Rails错误视为500错误?
答案 0 :(得分:11)
首先,如果您可以手动通知错误记录器错误,那可能是最好的做法。使Rails返回不同的HTTP状态代码可能会破坏应用程序的其他部分。
但是,如果您绝对必须这样做,则可以通过从救援响应哈希中删除相应的条目来指示Rails不返回404。您可以在初始化程序中执行此操作:
# config/initializers/rescue_responses_overrides.rb
ActionDispatch::ExceptionWrapper.rescue_responses
.delete('ActiveRecord::RecordNotFound')
现在,只要引发ActiveRecord::RecordNotFound
,Rails就会向浏览器发送500状态代码。您也可以一步删除所有条目:
ActionDispatch::ExceptionWrapper.rescue_responses.clear
要查看哪些其他错误Rails返回不同的状态代码,您只需在Rails控制台中打印哈希:
pp ActionDispatch::ExceptionWrapper.rescue_responses
答案 1 :(得分:9)
它引发了一个ActiveRecord :: RecordNotFound错误,Rails将其视为404错误而不是500错误
这是正确的做法。想象一下,搜索爬虫会点击您的博客应用并在您不存在的博客帖子上收到错误。如果您返回500
,则抓取工具会稍后再次尝试访问该页面。如果您返回404
,则抓取工具会识别该页面丢失,并可能会停止尝试。如果服务器以500
响应,某些浏览器甚至会显示自定义内置页面。
如果您仍想继续,您可以选择一些选项。您可以在顶级控制器中rescue_from
并将响应更改为您想要的任何内容。
class ApplicationController < ActionController::Base
rescue_from ActiveRecord::RecordNotFound, OtherError do |exception|
render nothing: true, status: 500 # nothing, redirect or a template
end
end
另一个选择是使用自定义exceptions_app
。它基本上是一个机架应用程序,在发生异常时会被调用,您可以使用请求/响应执行任何操作。您可以查看默认实现(ActionDispatch::PublicExceptions
)以获取灵感。