Handing Undeliverable Email Address in a Rails app

User can fat finger their email address during signup. We will not be able to send any emails for password reset, purchase confirmation etc. In this case, the system needs to handle the situation gracefully. Create a custom exception class:

class UndeliverableEmailError < StandardError
  attr_reader :object

  def initialize(object)
    @object = object

Use this custom exception class when the system encounters a situation where it cannot proceed further without manual intervention. In this case, we need to update user record with a deliverable email address. In my case, the background job processor uses this custom exception.

class NewCustomerFulfillmentJob < ApplicationJob
  queue_as :default

  def perform(user, password)
    if user.has_deliverable_email?
      PurchaseNotifierMailer.send_purchase_confirmation_email(user, password).deliver_now
      exception = UndeliverableEmailError.new(user)
      message = "User #{user.email} is not deliverable. User id: #{user.id}"
                                         env: request.env,
                                         data: {:message => message})

The exception message is constructed to provide the user id as well as the email address to aid in troubleshooting the problem. The users that are already verified by never-bounce-api API and have invalid email can be displayed in the admin dashboard. The user model has two boolean attributes, has_valid_email and deliverability_verified. The deliverability_verified attribute is set to true when the never-bounce-api call returns true. Exception notification gem is used to send the exception email.

def has_deliverable_email?
  return true if has_valid_email? && deliverability_verified?

  deliverability = EmailAddress.deliverable?(email)
  self.deliverability_verified = true
  self.has_valid_email = deliverability
  deliverability_verified? && has_valid_email?

If you were not sending an email and had to handle it in the code, you can do:

  raise UndeliverableEmailError.new(user), "User email cannot be used to send email"
rescue UndeliverableEmailError => e
  puts e.message 
  puts e.object 

In this article, we saw how the system can gracefully handle a case when it cannot fulfill its job without proper data.

Related Articles

Ace the Technical Interview

  • Easily find the gaps in your knowledge
  • Get customized lessons based on where you are
  • Take consistent action everyday
  • Builtin accountability to keep you on track
  • You will solve bigger problems over time
  • Get the job of your dreams

Take the 30 Day Coding Skills Challenge

Gain confidence to attend the interview

No spam ever. Unsubscribe anytime.