Sidekiq / active job not sending e-mails in production - ruby-on-rails

When I try to send e-mails with Sidekiq (5.1.3) and Rails (5.1.6) in production using ActiveJob's deliver_later, e-mails are not being sent (deliver_now works fine). The job gets processed and Sidekiq reports it as such. The logs show a successful start & done:
2018-09-14T14:12:18.031Z 14029 TID-mncgx ActionMailer::DeliveryJob JID-665575b056e61ef84a434c97 INFO: done: 0.84 sec
The only thing missing is the delivery of the actual e-mail. I've enabled 'raise_delivery_errors', but nothing is being raised. I'm sending my email through Mailgun.
I'm inclined to think something's going wrong with Sidekiq, because I had ActiveJob configured before (with the default adapter, :async) and deliver_later worked properly. Only after adding Sidekiq it stopped working. I've tried it with many different e-mails and in the end I created an extremely simple mailer, just for debugging this issue.
Here's the code of my 'job':
SimpleMailer.test.deliver_later
And here's the code of my mailer:
class SimpleMailer < ApplicationMailer
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
# en.simple_mailer.test.subject
#
def test
#greeting = "Hi"
mail to: xx, from: xx, subject: 'Well hello"
end
Thanks a lot in advance! I've been searching for quite some time now and have lost almost all inspiration - any help (on where to look) would be amazing. I could also provide more info, but I don't really know what's more to provide.

Related

Intermittent Rails mailer 'missing template' issue

I say intermittent, but it's really like 50% of the time. Here's what I'm using:
Rails 4.2.1
Sidekiq 3.4.1
I have a mailer that runs from ActiveJob, and half the time it is unable to find its associated template:
Missing template notifier/claim_email with "mailer". Searched in:
* "notifier"
The template is most definitely present and named properly:
$ ls app/views/notifier/
claim_email.html.erb
claim_email.txt.erb
Code:
def claim_email(subject, message)
#message = message
mail(
to: %Q{<#{ENV['DEFAULT_EMAIL']}>},
subject: subject,
)
end
Template:
<%= #message %>
I've also tried adding the :body option to send directly, but it inexplicably still tries to use the template(?!) I've restarted the app multiple times to no avail. This also always works in development. I'm baffled as to what could be happening here.
I figured it out. I was having the same issue as the person in this question:
Rails.root points to the wrong directory in production during a Resque job
My sidekiq jobs were not being properly restarted on deploy, which led them to have old pathnames for templates.
I had the same issue. Restarting sidekiq solved it for me. Good luck!

Sidekiq Delayed Mailer does not use updated mailer views after deploy

My production system is using Sidekiq's delayed mailer extension to send automated mails through Mailgun's smtp server.
All is well except there is a particular mail that when opened in its text alternative it uses the view from the previous deploy (while the html version is renders correctly).
Up to now I have restarted unicorn + sidekiq multiple times, I have created a new commit and deployed again while rewriting the whole view just in case but nothing works.
The production server is using unicorn, sidekiq connects to a redis instance on the same machine, while actionmailer is using the Mailgun SMTP. The mailer method is the following :
def new_shipment_added(shipment_id, user_id)
#shipment = Shipment.find(shipment_id)
#user = User.find(user_id)
return false if #shipment.nil? or #user.nil?
rcpts = Array.new
#user.email_addresses.each { |addrObj| rcpts << addrObj.address}
m = mail(to: rcpts, subject: t("subject_line_with_title", title: "#{#shipment.pickup.compact_address} - #{#shipment.delivery.compact_address}"))
end
I am including the method for context but I think that it's not causing the problem since html templates render correctly.
The bottom line of the question is : What could be causing the problem? ..and also how is sidekiq using the older template, since it can only be found in previous releases?

Rails 3 delayed job - upgrading to Rails 3 breaks delayed_job tasks

I'm in the middle of trying to upgrade pieces of our app to Rails 3, specifically our unit tests. I'm consistently running into an issue with delayed job and mailers, in particular, namely that the mailers aren't getting "sent" when the test is run.
To test emails sent, we run them all through an "assert_email" method in our test helper, which looks more-or-less like this:
def process_delayed_jobs
while Delayed::Worker.new(:quiet => true).send(:reserve_and_run_one_job) do
# nothing
end
end
alias_method :deliver_delayed_emails, :process_delayed_jobs
def assert_emails(number, skip_assertion = false)
deliver_delayed_emails # start with a clean slate
if block_given?
original_count = ActionMailer::Base.deliveries.size
yield
deliver_delayed_emails
new_count = ActionMailer::Base.deliveries.size
assert_equal original_count + number, new_count, "#{number} emails expected, but #{new_count - original_count} were sent" unless skip_assertion
else
assert_equal number, ActionMailer::Base.deliveries.size unless skip_assertion
end
end
We test on this like so:
assert_emails 2 do
Model.action_that_sends_mailer
end
This code works flawlessly in Rails 2, running delayed_job 2.0.5. On Rails 3 we are running 2.1.4.
Basically, this fails every time we test it, because "0" emails get sent. The mailers themselves are upgraded properly, and I've removed the erroneous ".deliver" from the method calls to fire them off. The delayed_jobs log is empty, so it doesn't look like anything is being processed.
I feel like I'm missing some kind of key (but easy) syntax problem here. Any help is appreciated.
Edit: I should also note that I've started the delayed_job process on my local machine with both "rails delayed_job start" and "script/delayed_job start." Neither fix the problem.
Turned out to be something unrelated to delayed_job.

Sending emails in test mode with ActionMailer in rails 3

I am having a slightly odd problem with sending mail in test mode with Rails 3
It seems that my mailers are not returning anything. For example I have a mailer called UserMailer. Users can make changes that require approval in the app so this has a method called changes_approved that should send the user an email notifying them that their changes have been approved.class
UserMailer < ActionMailer::Base
default :from => "from#example.com"
def changes_approved(user, page)
#user = user
#page = page
mail(:to => user.email, :subject => "Your changes have been approved")
end
end
In my controller I have the following line
UserMailer.changes_approved(#page_revision.created_by, #page_revision.page).deliver
However my tests fail at this point with the error:
undefined method `deliver' for nil:NilClass
When I trigger the same actions on the development site tho (http://localhost:3000 through a browser), the emails are sent out correctly and everything works quite happily
And to add further confusion, I am using devise for authentication and the emails for that seem to be working correctly both in test and development modes. Certainly I am not getting this same error and according to my email-spec tests, everythings working
So this leads me to believe that I have a problem with my mailers rather than my test mail config per se but I have no idea what. Any suggestions would be much appreciated
Thanks
I used https://gist.github.com/1031144
to convert
# Rails 2 method:
UserMailer.should_receive(:deliver_signup)
to
# Cumbersome Rails 3 method:
mailer = mock
mailer.should_receive(:deliver)
UserMailer.should_receive(:signup).and_return(mailer)
I had a similar problem - probably the UserMailer.changes_approved method is being replaced with a mock method, which returns nil (I wasn't using shoulda for that test, but that's my best guess).
My code looked like this (modified to use your example):
UserMailer.expects(:changes_approved).once
I fixed it with an additional stub:
#mailer = stub(:deliver)
UserMailer.expects(:changes_approved).once.returns(#mailer)
The nil is now replaced with #mailer.
To test the delayed action mailer we need to first change the configuration of delayed_job (in config/initializers/delayed_job_config.rb) to
Delayed::Worker.delay_jobs = !Rails.env.test?
and in your tests the expectation should be set to
mock_mail = mock(:mail)
mock_mail.should_receive(:deliver)
UserMailer.should_receive(:changes_approved).with(user, page).and_return(mock_mail)
Well I have found the answer,
it looks like the problem was in the way I was testing these mailers. In each of the controller tests I had a line similar to
UserMailer.should_receive(:changes_approved).with(user, page)
Whilst this test was passing fine, it appeared to break the mailer itself. I have removed this line from the tests and now they pass ok. Subsequent tests against ActionMailer::Base.deliveries.last to check the details of the sent email are correct appear to be ok so I am happy that this line is not neccessary.
If anyone has an explanation as to why this breaks tho, I would be interested to find out
Thanks anyways

Problems with ActionMailer: 501 <>: missing or malformed local part

I'm having trouble sending mail using SMTP from a Rails app. I have a Mailer class:
class Mailer < ActionMailer::Base
def newsletter_confirmation(subscription)
recipients "my-valid-email#gmail.com" # this is set to my email
# just for testing purposes and will
# be changed to subscription.email
from "\"my-valid-helo-domain.net\" <noreply#my-valid-helo-domain.net>"
subject "Confirm your subscription"
body :subscription => subscription
end
end
When I try to send the mail, I get a Net::SMTPSyntaxError:
501 <["noreply#my-valid-helo-domain.net"]>: missing or malformed local part
If I comment out the from field, the mail gets delivered ok, but with the from information missing (obviously). Any ideas on what I'm doing wrong?
Thanks.
Edit: I'm using Rails 2.3.2 and Ruby 1.9.1
The error code and the description of the error states that this is an error on the mail server.
I suggest you check the mail servers to pinpoint the error.
When it comes to ActionMailer it is supposed to raise an exception if the configuration parameter raise_delivery_errors is set (default in Production but not in Development I believe), so you can check that one and try to resend if it triggers.
EDIT:
Here is the solution (it's a Ruby/Rails 1.9 bug):
https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2340-action-mailer-cant-deliver-mail-via-smtp-on-ruby-191
and the patch:
https://rails.lighthouseapp.com/projects/8994/tickets/2340/a/104008/action_mailer-ruby-1.9-from-address-fix.patch
It is a known bug. https://rails.lighthouseapp.com/projects/8994/tickets/2340

Resources