delayed_job 在具有 AASM 的 ActiveRecord 模型上 - 吞下失败的方法错误,抛出 "wrong number of arguments"

delayed_job on ActiveRecord model with AASM - failing method error swallowed, throws "wrong number of arguments" instead

在我的 Rails 4 应用程序中,我有一个带有 AASM 列的 ActiveRecord 模型。当我对 delayed_job_active_record 使用失败的方法时,它吞下错误并抛出与 AASM 相关的其他内容。

class MyModel < ActiveRecord::Base
  include AASM

  aasm do
    # aasm setup here
  end

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

MyModel.joberrorZeroDivisionError 可预见地失败。但是,当我从 delayed_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'

full stacktrace here

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

我读到 delayed_job 对您希望它执行的方法进行了一些序列化,但我不太了解这样做的后果,无法知道为什么会导致此问题或如何解决此问题。

这个 delayed_job 代码就是问题所在。当 delayed_job 遇到错误时,它会在它可以调用的对象上寻找一些东西,在本例中是任何名为 "error":

的东西
# 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 的 aasm 状态。所以每当发生错误时,delayed_job 救出然后尝试调用这个错误状态作为方法,但失败了。这显然只发生在被调用的代码抛出错误时,并且只有当它是 运行 via delayed_job.

时才会发生