使用AirBrake或ExceptionNotifier等工具发送延迟作业时,获取错误报告的正确方法是什么?
我尝试创建自己的延迟作业类,但Mailer.welcome()
(或类似)创建的邮件对象未正确序列化。我还尝试在error(job, exception)
和PerformableMailer
类中添加PerformableMethod
方法,但我认为通常与序列化相关的错误更多。我为序列化尝试了psych和sych。
答案 0 :(得分:7)
总体而言,解决方案非常简单。如果您正在 Object (如MyClass.new.delay.some_method
)上执行delayed_job,则需要将错误处理定义为对象方法。如果您在 Class (如MyTestMailer.test_email ...
)上执行delayed_job,则需要将错误处理定义为类方法。
假设您有一封名为TestMailer
的邮件。解决方案是将错误处理定义为类方法,而不是对象方法:
# Your rails mailer
class TestMailer
# Whoa! error has to be a class method!
def self.error(job, e)
puts "I can now handle test mailer errors in delayed job!!!!"
end
end
现在上面的def self.error
方法将用作延迟作业中的错误回调!
或者,如果您希望能够处理所有操作邮件错误,
class ActionMailer::Base
def self.error(job, e)
puts "I can now handle all mailer errors in delayed job!!!"
end
end
原因是因为DelayedJob的内部PerformableMethod
处理错误的方式。 PerformableMethod
有两件事:目标对象和目标方法。在Action Mailer的情况下,目标对象不是对象,而是您的邮件程序类TestMailer
。目标方法是您使用的邮件方法,例如test_mail
。 DelayedJob在目标对象上查找所有挂钩(error
,before
,after
等)。但在我们的例子中,目标对象就是类本身。因此,必须将钩子定义为类方法。
DelayedJob
处理ActionMailer邮件的方式有点笨拙。如果添加对象方法而不是类方法,则会引发不需要的异常。例如,这是代码:
# In <delayed-job-gem>/lib/delayed/performable_method.rb
module Delayed
class PerformableMethod
# line #7
delegate :method, :to => :object
ruby中的每个对象都有一个method
函数,用于获取该类中方法的原始引用。但是在DelayedJob中 - 这个原始method
函数已被委托给其他一些目标对象。这种破解使我们无法正常使用def error
函数来处理作业错误。
编辑:添加脚注,轻微澄清
编辑2:重新排序的答案
答案 1 :(得分:2)
首先,一个包含在邮件程序中的模块,可能包含其他延迟的工作:
module Delayed
module Airbrake
# Send error via Airbrake
def error(job, e)
::Airbrake.notify(e, :component => job.name, :action => 'perform', :parameters => {:job => job.inspect})
end
end
端
然后包括它:
Delayed::PerformableMailer.send(:include, Delayed::Airbrake)