Debugging Rails Mails with Mailhog

Testing and troubleshooting troubles with mailers do not have to be a pain in the butt.

04 rails mails mailhog

No one likes dealing with email code. Although Rails mailers make it easy to send e-mails, styling emails can be a compatibility nightmare and testing emails often involves hacks to intercept them. Another issue is that your email service of choice may not be available at all times for debugging, or you may not even have chosen your email service yet.

Do not despair, though, internet denizen, for not all is lost, as in the mythical land of Go many brave women and men have teamed up to bring us Mailhog. Mailhog is a simple service that traps emails before they are sent and lets you preview them in its web interface; in more concise terms, it's a SMTP server with a web interface. Using Mailhog, we can:

  • easily verify that Rails does indeed send our emails,
  • preview what they look like in a simple interface,
  • debug occasional issues using the Chaos Monkey function and
  • even send them on their merry way to reach their final destination if we so desire.

Setting up Mailhog

Setting up Mailhog is easy. You can either install it via Homebrew using brew install mailhog, or you can set it up as a Docker image in case you are running Rails through Docker. Then, all you have to do is set your development SMTP settings to match Mailhog's.

# config/environments/development.rb

Rails.application.configure do
  config.action_mailer.perform_deliveries = true
  config.action_mailer.smtp_settings = {
    address: 'localhost',
    port: 1025

Once you have done that (and restarted your Rails server for good measure), go ahead and fire up Mailhog and send some emails. You should see them appear in the Mailhog web interface, accessible on the port 8025.

Jim the Chaos Monkey

But what if we want to test something more advanced? In the real world, mails get dropped, connections get slow and disconnects happen. Your application should be able to handle occasional interruptions in the email service - if nothing, then for that one user who will be angry that he is not receiving emails on the Raspberry Pi he is hosting on his home connection (go to hell Steve, no one cares about your Gentoo setup).

Mailhog comes with a feature that's called Jim - yes, that's a great feature name - and Jim will mess up your emails occasionally so that they get rejected, dropeed, rate limited or other fun things that you never plan for but that always seem to happen. While this seems like the opposite of what you want in development, it is an invaluable tool in stress-testing your application and ironing out bugs before the final release. You can enable Jim via command-line options, or via the web interface.

Trap and Release

The final feature of Mailhog that I want to talk about is the "release" option. Mailhog will trap all outgoing mails by default, but you can also set it up with credentials to your favourite transactional email service. If they are set up, you will gain the option to release the emails to their actual intended destination to ensure your integration with the email service is working properly. Such a strategy also helps with debugging issues with the email service that you are using - if the email reaches Mailhog safely, your app is not the one to blame.

To summarize, Mailhog is a simple, yet effective tool to ensure all of your emails work the way it should without actually sending them out. I hope you give it a shot!

Leave a comment Be the first!