Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActionMailer::Base::NullMail when trying exception_notification in development

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!

like image 403
svoop Avatar asked Mar 10 '13 13:03

svoop


2 Answers

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
like image 169
spyle Avatar answered Oct 16 '22 00:10

spyle


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
like image 4
TomDunning Avatar answered Oct 15 '22 23:10

TomDunning