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.