I am using Postmark to handle all email in my Rails 3 app, using postmark-rails gem.
Now and then an user introduces a wrong email or a non-existing one with ends up giving hardbounces. Postmark raises Postmark::InvalidMessageError
errors to handle this issue, that my users receive as a non-descriptive 500 error.
I'd like to handle those errors into my responsive interface and I was wondering what would be the best strategy. I have now a few mailers already with several dozens amongst all, so I don't want to add begin-raise
blocks to all those methods. Adding this begin-raise to controllers also doesn't seem the most elegant solution.
I've been reading about adding a rescue_from
block to my ApplicationController
, but then I don't know how to handle this in the interface (maybe by calling a method that uses errors
method?)
I'd like to listen to your thoughts before plumbering.
Any ideas?
We had to deal with the same problem in Beanstalk. First of all we turned off "raise_delivery_errors" in production then we implemented an override method for ActionMailer::Base that allowed us to change that setting on the fly for specific deliveries. Like this:
AccountMailer.raise_errors do
AccountMailer.deliver_welcome_email(@account)
end
That allowed us to control when exactly we want delivery exceptions appearing and avoid problems when such errors were breaking something they shouldn't. Usually there are only one or two places where you'd want to put that override. In our case it's Forget Password and Invite User functions, when it's crucial to let users know that their password reset email/invitation wasn't delivered. Having a delivery exceptions somewhere inside a background-running job doesn't help anyone.
After we had that in place we added a rescue_from to our ApplicationController that would set flash[:alert] and redirect back.
def postmark_delivery_error(exception)
if address = derive_email_from_postmark_exception(exception)
link = %Q[<a href="#{ reactivate_email_bounce_path(address) }">reactivating</a>]
msg = "We could not deliver a recent message to “#{ address }”. The email was disabled due to a hard bounce or a spam complaint. You can try #{ link } it and try again."
else
msg = "We could not deliver a recent message. The email was disabled due to a hard bounce or a spam complaint. Please contact support."
end
flash[:alert] = msg
redirect_to :back
end
reactivate_email_bounce_path links to a controller that uses Postmark API to reactivate bounces. You can find more details about it here:
http://developer.postmarkapp.com/developer-bounces.html
So after you have all that in place your end user can have a pretty nice experience dealing with delivery errors, something that's not usually addressed in web apps. It looks like this in Beanstalk:
And not only a user can see that his email bounced, he can also reactive it himself:
Hope this helps.
Ilya Sabanin http://twitter.com/isabanin