Question

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?

Was it helpful?

Solution

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:

Beanstalk reactive bounce

And not only a user can see that his email bounced, he can also reactive it himself:

Beanstalk reactivate bounce

Hope this helps.

Ilya Sabanin http://twitter.com/isabanin

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top