Quick tips — Action mailer rescue_from method

João Paulo Lethier
2 min readFeb 25, 2017

--

Around three months ago, I tried to solve a problem with exceptions on action mailer and I did not find a way to fix it in a simple way for all mailers. The problem was that we had action mailer configured to send emails through sparkpost, and sparkpost throws an exception when we tried to send an email to a recipient that is invalid or already mark us as spam or previous email sent to it was bounced, and we want to mark this emails as rejection to not try to send emails to this anymore.

So, what I want to do was catch those exceptions and treat it to save this information and do not send next emails to those recipients. The only solution I found was to use begin and rescue everywhere I call a mailer, but this was not suitable for me because in the project I was working we use all mailers with delay method, running the mailers on sidekiq. So, everytime a mailer throws an exception the mailer job was sent to sidekiq retry queue and it keeps retrying and throws exception indefinitely.

This week, looking for a solution for this again, I discovered that with rails 5 (and the project was updated to rails 5 last december), there is a new method for ActionMailer. The rescue_from method that we already know for rails controllers now exists for ActionMailer too. So, I could implement something like this:

class ApplicationMailer < ActionMailer::Base
rescue_from SimpleSpark::Exceptions::Error do |exception|
# besides the exception variable, you have here the message method that has all message attributes, so you can save that message.to(it is always an array) are invalid emails
message.to.each do |email|
EmailRejection.create(email: email)
end
end
end

In this example, I just have a simple model called EmailRejection that saves all email that is invalid or reject my emails before(spam, bounce, etc). The message method in this rescue_from gives me access to all message attributes(to, from, subject, etc), and message.to is always an array, a list of emails, even when you are sending this to a single email, it will be a array with one string.

So, this way all mailers that inherited from my ApplicatioMailer now knows how to deal with sparkpost exceptions, just like we are used to use rescue_from on controllers for not found or permission denied, for example. And now I have all rejected emails saved on a table, I just need to implement a interceptor to not send email to those emails anymore.

--

--

No responses yet