Сообщение об ошибке при отправке электронной почты с delayed_job
Как правильно получать отчеты об ошибках при использовании таких инструментов, как AirBrake или ExceptionNotifier, для отправки по почте отложенных заданий?
Я пытался создать свой собственный класс отложенного задания, но почтовый объект, созданный Mailer.welcome()
(или подобное) не правильно сериализовано. Я также попытался добавить error(job, exception)
метод к PerformableMailer
а также PerformableMethod
классы, но я получил больше ошибок, как правило, связанных с сериализацией, я считаю. Я попробовал и сериал, и псих, и сыч.
2 ответа
Обновленное решение
В целом решение довольно простое. Если вы делаете delayed_job на объекте (например, MyClass.new.delay.some_method
), то вам нужно определить обработку ошибок как метод объекта. Если вы делаете delayed_job в классе (например, MyTestMailer.test_email ...
), то вам нужно определить обработку ошибок как метод класса.
Допустим, у вас есть почтовик 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
Каждый объект в рубине имеет method
функция, которая используется для получения необработанной ссылки на метод внутри этого класса. Но в DelayedJob - это сырье method
Функция была отчасти делегирована другому целевому объекту. Этот хак мешает нам нормально использовать def error
функция для обработки ошибок работы.
Редактировать: добавлена сноска, незначительное уточнение
Изменить 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)