1

我想使用 Ruby 核心的 Timeout 使 ActiveRecord 查询超时,但是 ActiveRecord 似乎正在捕获Timeout::Error并将其包装在ActiveRecord::StatementInvalid异常中。

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

这很不幸,因为我还想捕获生成ActiveRecord::StatementInvalid异常的真正 SQL 错误并以不同的方式处理它们。有没有办法区分两者?(比匹配“执行已过期”的异常消息更清晰)。

4

1 回答 1

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

如果你想接收 Timeout::Error 你应该在 timeout 块中捕获所有其他异常。

于 2012-11-15T23:59:29.080 回答