2012-11-09 105 views
1

我想超時從Ruby核心使用超時ActiveRecord查詢,但ActiveRecord似乎趕上Timeout::Error幷包裝它在ActiveRecord::StatementInvalid異常。超時ActiveRecord查詢

> Timeout::timeout(3) { sleep 4000 } 
Timeout::Error: execution expired 
... 

> Timeout::timeout(3) { ActiveRecord::Base.connection.execute "select pg_sleep(4)"} 
(3001.5ms) select pg_sleep(4) 
: execution expired: select pg_sleep(4) 
ActiveRecord::StatementInvalid: : execution expired: select pg_sleep(4) 
... 

這是不幸的,因爲我也想趕上真正的SQL錯誤產生ActiveRecord::StatementInvalid例外,區別對待。 有沒有辦法區分兩者? (比「執行過期」的異常消息匹配更乾淨)。

+0

您必須實際查看錯誤消息。 – muichkine

回答

0

嘗試使用此代碼:如果你想收到超時::錯誤,你應該抓住在超時塊中的所有其它的異常

begin 
    Timeout::timeout(3) do 
    begin 
     ActiveRecord::Base.connection.execute "select pg_sleep(4)" 
    rescue ActiveRecord::StatementInvalid 
     # handle ActiveRecord::StatementInvalid exception 
    end 
    end 
rescue Timeout::Error 
    # handle Timeout::Error exception 
end 

+0

'Timeout :: timeout'看似簡單,但會導致非常不可預知的結果。這些文章解釋了可能發生的錯誤種類: - https://jvns.ca/blog/2015/11/27/why-rubys-timeout-is-dangerous-and-thread-dot-raise-isterrifying/ - http://www.mikeperham.com/2015/05/08/timeout-rubys-most-dangerous-api/ – odlp