January 15, 2018
This blog is part of our Rails 5.2 series.
Rails allows sending emails asynchronously via Active Job.
Notifier.welcome(User.first).deliver_later
It uses ActionMailer::DeliveryJob
as the default job class to send emails.
This class is
defined internally
by Rails.
The DeliveryJob
defines handle_exception_with_mailer_class
method to handle
exception and to do some housekeeping work.
def handle_exception_with_mailer_class(exception)
if klass = mailer_class
klass.handle_exception exception
else
raise exception
end
end
One might need more control on the job class to retry the job under certain conditions or add more logging around exceptions.
Before Rails 5.2, it was not possible to use a custom job class for this purpose.
Rails 5.2 has added a feature to configure the job class per mailer.
class CustomNotifier < ApplicationMailer
self.delivery_job = CustomNotifierDeliveryJob
end
By default, Rails will use the internal DeliveryJob
class if the
delivery_job
configuration is not present in the mailer class.
Now, Rails will use CustomNotifierDeliveryJob
for sending emails for
CustomNotifier mailer.
CustomNotifier.welcome(User.first).deliver_later
As mentioned above CustomNotifierDeliveryJob
can be further configured for
logging, exception handling and reporting.
By default, deliver_later
will pass following arguments to the perform
method of the CustomNotifierDeliveryJob
.
class CustomNotifierDeliveryJob < ApplicationJob
rescue_from StandardError, with: :handle_exception_with_mailer_class
retry_on CustomNotifierException
discard_on ActiveJob::DeserializationError
def perform(mailer, mail_method, delivery_method, *args)
logger.log "Mail delivery started"
klass = mailer.constantize
klass.public_send(mail_method, *args).send(delivery_method)
logger.log "Mail delivery completed"
end
def handle_exception_with_mailer_class(exception)
if klass = mailer_class
klass.handle_exception exception
else
raise exception
end
end
end
We can also simply inherit from the ActionMailer::DeliveryJob
and override the
retry logic.
class CustomNotifierDeliveryJob < ActionMailer::DeliveryJob
retry_on CustomNotifierException
end
If this blog was helpful, check out our full blog archive.