为什么我无法在ActiveRecord中处理限制异常?

时间:2016-01-11 19:23:43

标签: ruby-on-rails ruby exception activerecord

今天我找到了一个我无法处理的奇妙例外。

当我写这段代码时:

def example
  Integer('example show')
rescue 
  p 'All is good, I handle it'
end

> example
#=> 'All is good, I handle it'

但是当ActiveRecord抛出异常时,我得到:

def example
  SomeModel.all.limit('example show')
rescue
  p 'All is bad, I cannot handle it'
end

> example
#=> ArgumentError: invalid value for Integer(): "example show"

我认为这是一个神奇的深度异常或嵌套异常,但这也很好用:

class A
  def a
    b
  end
  def b 
    Integer('show example')
  end
end

begin
  A.new.a
rescue
  p 'All is good, I can handle it'
end
=> 'All is good, I can handle it'

1 个答案:

答案 0 :(得分:3)

这种情况正在发生,因为SomeModel.all.limit的评估会延迟到rescue阻止之外。 all.limit会返回一个ActiveRecord::Relation,它实际上并不运行,所以example返回正常,然后您尝试使用该值并且Rails无法转换{ {1}}到example show。这是我的控制台的演示:

Integer

我建议您自己处理> def example * User.all.limit('something') * rescue * puts 'Rescued' * end => :example > foo = example => #<#<Class:#<ActiveRecord::Relation::ActiveRecord_Relation_User:0x007ffb5b52e168>>:0x3ffdada970b4> > foo.to_a ArgumentError: invalid value for Integer(): "something" something的转换,以便在Integer方法中正确捕捉到这一点。否则,每当您访问example的返回值时,您都需要rescue,这不会很顺利。您还可以通过调用example强制example内的关系实例化。这将引发您的SomeModel.all.limit('something').load可以按预期方式捕获的异常。