ActionMailer::Base::NullMail when trying exception_notification in development
Asked Answered
T

2

7

I'd like to add the exception_notification gem to our app, however, this happens when I try to manually trigger a mail:

exception
# => #<ZeroDivisionError: divided by 0>
ExceptionNotifier::Notifier.exception_notification(request.env, exception)
# => #<ActionMailer::Base::NullMail:0x007fa81bc7c610>
ExceptionNotifier::Notifier.background_exception_notification(exception)
# => #<ActionMailer::Base::NullMail:0x007fa81bf58190>

In the above example, the console is at a breakpoint inside rescue_from Exception in the ApplicationController after a deliberate 1/0 in some controller.

I'm using delayed_job as well, but - no surprise - ExceptionNotifier::Notifier.background_exception_notification(exception).deliver does not spool anything.

I've already set config.consider_all_requests_local = false in development, but still exception_notification instantiates NullMail. In other parts of the app, mailers work just fine and use sendmail.

Any ideas what I'm doing wrong here? Thanks for your help!

Taco answered 10/3, 2013 at 13:10 Comment(0)
Y
10

Likely you are using an old version of the ExceptionNotifier and a newer version of ActiveMailer::Base. Not calling the mail command within the email functionality will result in the ActionMailer::Base::NullMail instance returned rather than a Mail instance.

From documentation:

class Notifier < ActionMailer::Base
  default :from => '[email protected]',
         :return_path => '[email protected]'

  def welcome(recipient)
    @account = recipient
    mail(:to => recipient.email_address_with_name,
         :bcc => ["[email protected]", "Order Watcher <[email protected]>"])
  end
end
Yuonneyup answered 2/4, 2013 at 14:23 Comment(0)
S
4

I had my tests / rspec returning NullMail objects. the solution was simple, my code was:

def my_mail(foo)
   mail(
     to: to,
     from: from,
     subject: @sample_item.campaign_market.campaign.translation_for(language_id, 'sample_item_mailer.request_review.subject'),
     content_type: "text/html"
   )
   @sample_item.update_attributes!({feedback_requested: true, review_requested_at: Time.now})
   TrackingService::Event.new(@user, @user.market, 'sample_items', "request_review_email #{@sample_item.id}").call()
end

what's not immediately clear from the ruby docs is that you need to return the mail function,not just execute it. If you need to do something after building the mail object make sure you return the mail at the end. like so:

def my_mail(foo)
   m = mail(
     to: to,
     from: from,
     subject: @sample_item.campaign_market.campaign.translation_for(language_id, 'sample_item_mailer.request_review.subject'),
     content_type: "text/html"
   )
   @sample_item.update_attributes!({feedback_requested: true, review_requested_at: Time.now})
   TrackingService::Event.new(@user, @user.market, 'sample_items', "request_review_email #{@sample_item.id}").call()
   return m
end
Secession answered 17/7, 2014 at 16:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.