2

在我的 Rails 4 应用程序中,我有一个带有 AASM 列的 ActiveRecord 模型。当我使用带延迟作业活动记录的失败方法时,它会吞下错误并抛出与 AASM 有关的其他内容。

class MyModel < ActiveRecord::Base
  include AASM

  aasm do
    # aasm setup here
  end

  def self.joberror
    1/0 #bad code here
  end
end

MyModel.joberror可预见地失败了ZeroDivisionError。但是,当我从 delay_job_active_record ( MyModel.delay.joberror) 内部运行此方法时,会吞下正确的错误,而是抛出此错误:

wrong number of arguments (2 for 0)
/Users/myhome/myproject/.gems/gems/aasm-4.0.5/lib/aasm/persistence/base.rb:67:in `block (2 levels) in state_with_scope'

完整的堆栈跟踪在这里

这指向 aasm gem 中的代码,尽管此方法根本不涉及 aasm,甚至也不涉及MyModel. 但是,如果我注释掉 aasm 代码,它会返回正确的 ZeroDivision 错误。

我已经读到delayed_job 对您希望它执行的方法进行了一些序列化,但我不明白这样做的后果足以知道它为什么会导致这个或如何解决它。

4

1 回答 1

1

这个delayed_job 代码是问题所在。当delayed_job 遇到错误时,它会在对象上查找它可以调用的东西,在这种情况下,任何名为“错误”的东西:

# lib/delayed/backend/base.rb: 96    
rescue => e
  hook :error, e
raise e

# lib/delayed/backend/base.rb: 111
def hook(name, *args)
  if payload_object.respond_to?(name) # <--- my object has an unrelated method "error"
    method = payload_object.method(name)
    method.arity == 0 ? method.call : method.call(self, *args)
  end
rescue DeserializationError
end

就我而言,我有一个名为error. 所以每当发生错误时,delayed_job 就救了出来,然后尝试把这个错误状态作为方法调用,结果失败了。这显然仅在被调用的代码引发错误时发生,并且仅在通过delayed_job 运行时发生。

于 2015-01-19T17:52:38.120 回答