Rescue_from不会从视图或帮助程序中解救Timeout :: Error

我的应用程序控制器中有一个around_filter来封装超时块中的所有操作,以便在达到30秒Heroku限制之前操作失败。 我还有一个来自Timeout :: Error的rescue_来干净地拯救这些超时。 不幸的是,rescue_from只在某些时候起作用。

如果在控制器内执行时发生超时,它可以正常工作,但如果超时发生在视图或帮助器中则无法解决。

Interout :: Errorinheritance的Interrupt和SignalException都没有正确地进行救援。 但是,抢救Exception本身确实可以在视图和帮助程序中正确地进行救援。

around_filter :timeout rescue_from Timeout::Error, :with => :timeout_rescue def timeout Timeout::timeout(10){ yield } end def timeout_rescue # Rescued end 

有没有其他方法来拯救Timeout :: Error让这个工作?

我遇到了同样的问题。 我正在使用Rails 3 + Rack :: Timeout并尝试在ApplicationController中使用rescue_from。

我最终用这个……

 rescue_from Exception do |exception| if exception.is_a?(Timeout::Error) || /execution expired/ =~ exception.message # rescued from timeout error end raise end 

UPDATE

我修补了机架超时gem以正确返回Timeout :: Error。 这是一个线程问题。 官方gem已更新: https : //github.com/kch/rack-timeout

新的首选方法如下。 一般来说,从Exception中拯救并不是一个好主意,如果可能的话应该避免。

 class ApplicationController < ActionController::Base rescue_from Timeout::Error, with: :handle_timeout def handle_timeout(exception) # handle timeout error end end 

当Timeout需要引发exception以终止执行时,它不会引发Timeout :: Error。 如果确实如此,花园式的救援将陷入其中,而这不是你想要的。 相反,它引发了自己的Exception,它派生自:: Exception,因此除了救援Exception之外,它还会受到任何拯救。 或者 – 你可以将你自己的Exception作为第二个参数传递给Timeout :: timeout,这样你就可以拯救它。 请注意,Timeout将重新提升它。

读取timeout.rb代码(在ruby200 / lib / ruby​​ / 2.0.0中)。 它很短,很有趣,会告诉你它是如何工作的。