What's the proper way to get error reports, when using a tool like AirBrake or ExceptionNotifier from mailing delayed jobs?
I tried to creating my own delayed job class, but the mail object created by Mailer.welcome()
(or similar) is not serialized correctly. I also tried adding an error(job, exception)
method to the PerformableMailer
and PerformableMethod
classes, but I got more errors generally related to serializing I believe. I tried both psych and sych for the serialization.
Updated Solution
Overall the solution is quite simple. If you have are doing delayed_job on an Object (like
MyClass.new.delay.some_method
), then you need to define error handling as an object method. If you're doing delayed_job on a Class (likeMyTestMailer.test_email ...
), then you need to define error handling as a class method.Let's say you have a mailer called
TestMailer
. The solution is to define the error handling as a class method, not an object method:Now the above
def self.error
method will be used as the error callback in the delayed job!Or if you want to be able to handle all action mailer errors,
The reason is because of the way DelayedJob's internal
PerformableMethod
handles errors. APerformableMethod
has two things: a Target Object, and a Target Method. In Action Mailer's case, the Target Object is not an object, but your mailer classTestMailer
. The target method is the mail method that you use, saytest_mail
. DelayedJob looks for all the hooks (error
,before
,after
, etc) on the Target Object. But in our case, the Target Object is the class itself. Hence the hooks have to be defined as class methods.The way
DelayedJob
handles ActionMailer mails is a little hacky. If you add an object method instead of a class method, it throws an unwanted exception. For example, here is the code:Every object in ruby has a
method
function, which is used to get a raw reference to a method inside that class. But in DelayedJob - this rawmethod
function has been kind of delegated to some other target object. This hack prevents us from normally using thedef error
function for handling job errors.Edit: Added footnote, minor clarification
Edit 2: Reordered answer