SMTP errors at sending emails with ruby on rails - ruby-on-rails

I've been trying to send some test newsletter using my gmail account as smtp, but when i tried to send to multiple recipients - ['emai#laddr#email.com, emailaddr2#email.com'] - in this case the first email address is incorrect - it gives me an error 555 - 5.5.2 Syntax error and the process stops without passing through the next email addreses.
My question is:
is there a possibility to bypass those kind of errors in order to skip the incorrect addresses and to continue sending the emails?

You can set ActionMailer to ignore delivery errors, but that's not really considered best practice in a production environment.
# environment.rb (or development/test etc)
ActionMailer::Base.raise_delivery_errors = false
If you don't have a lot of recipients, you could try looping through the array of addresses and sending an email for each one, rescuing a delivery error and adding a message to the log.
# Model
def send_emails(addresses)
addresses.each do |address|
begin
YourMailer.deliver_method(email)
rescue
logger.error "Could not send email to #{email}"
end
end
end

Related

Is there any way to prevent Rails autocleaning class variables when testing emails?

I testing a Rails application that sends emails in some situations. It's an API.
For the testing, I'm using the Airborne gem, which makes API testing pretty easy. All went correct except when I had to test the email deliveries. I tried the following:
it "blah" do
//Code that makes my API send an email
puts ActionMailer::Base.deliveries.inspect
end
But deliveries array is always empty. I also tried with Emails.deliveries.inspect. Emails is my custom Mailer that inherits ActionMailer::Base.
I ended reading the API documentation of ActionMailer and met the interceptor concept. Interceptors doesn't work in :test delivery method so I switched to :smtp. In fact, the emails are being sent correctly, but I can not access them on the tests to make expectations.
My interceptor code is this right now
initializers/email_interceptor.rb
class EmailInterceptor
##msgs = []
def self.delivering_email(message)
puts message
//Rails.logger.debug "Email being sent: " + message.to_s
##msgs << message
Rails.logger.debug "Actual messages array: #{##msgs}"
end
def self.msgs
##msgs
end
end
ActionMailer::Base.register_interceptor(EmailInterceptor)
All OK. The debug messages print the array being populated correctly. But the variable is cleaned before my test statement is executed.
EDIT: The code above is executed when I run my test suite. But the variable is empty accessed from the test itself.
//test code
puts EmailInterceptor.msgs.inspect
=> []
Is there any way to prevent this behavior?
You may have config.action_mailer.perform_deliveries = false in your test.rb config. It seems like you should really be using config.action_mailer.delivery_method = :test since this will allow ActionMailer::Base.deliveries to be populated, which makes for easier and more reliable testing. Do you really need interceptors for your tests?

Why are emails not getting in the ActionMailer::Base.deliveries table?

Currently in my development environment I am not seeing anything in the ActionMailer::Base.deliveries table after mail is used. Is there a setting I am missing?
config/environments/development.rb: config.action_mailer.delivery_method = :test.
app/mailers/notifier.rb
def send_email(user)
mail(:to => user.email, :subject => "Welcome to our website!")
end
These are the tests I'm running:
When /^I signup$/ do
visit signup_path
#user = FactoryGirl.build(:user)
fill_in "user_email", :with => #user.email
fill_in "user_password", :with => #user.password
click_button "Join now"
end
Then /^I should receive a confirmation email$/ do
email = ActionMailer::Base.deliveries.last
email.subject.should == "Welcome to our website!"
end
Right now I get the following error for the I should receive a confirmation email step:
undefined method subject for nil:NilClass (NoMethodError)
Thanks!
Another possibility might be that in config/environments/test.rb you have
config.action_mailer.delivery_method = :test
but you have set
config.action_mailer.perform_deliveries = false
so changing to
config.action_mailer.perform_deliveries = true
made it work again in my case.
Old question, I know, but a couple things come to mind:
You talk about the configuration of your development environment (config/environments/development.rb), but it's your test that isn't working. Check config/environments/test.rb and maybe config\application.rb.
I actually wanted to see the email array in my development environment, but it always returned nil in the console. I finally realized that because the array is just a memory object, not in the database, the console (rails c) can't see what's going on in the server (rails s). When I added <%= ActionMailer::Base.deliveries.count %> to a view, I could immediately see the array getting populated in development.
Another "I can't see that process from the console" situation arises if you are using a separate thread or task for sending emails. With delayed_job, I found this answer suggesting you can look at the job (not the actual email) using Delayed::Job.last.handler, which does look at the database so works across processes. However this only works while the job is still in the database, i.e. before a worker has processed it.
The error you are getting says that email is nil. In other words, the deliveries.last method is returning nil because there are no emails in it.
There could be a number of reasons... I'm assuming that you are using cucumber as the testing mechanism?
1. Verify that 'click_button' submits
You could try to put puts or log statements. Make sure that when you run the cucumber feature, it actually prints. Sometimes these things don't work because the front-end logic doesn't work and the test is failing correctly. In other words, the controller endpoint you are expecting to be triggered isn't being triggered.
2. Verify that 'send_email' is right - using a unit test
Next, verify that you are actually sending email. Write a unit test to verify this works. This should be quick and easy to get going. Plenty of articles out there.
Lastly, not really related, but you might want to roll with email-spec which should provide some nice testing methods so you don't have to reinvent the wheel.
After making the changes answered by #Dominik Steiner, if it still didn't work ,
another possibility might be that in config/initializers/mailer.rb, you should have :
ActionMailer::Base.delivery_method = :test
Above was missing in my case and it worked now.

ActionMailer sends emails even though it failed with ArgumentError: A sender required to send a message

Looks like my emails raising errors and sending.
I'm receiving emails and also I get this error on "rake jobs:work" console:
Class#deliver_and_save failed with ArgumentError: A sender (Return-Path, Sender or From) required to send a message - 1 failed attempts
But when I step through my debugger, I can see that there is a from:
> email.from
=> ["my#email.com"]
> email_draft.From
=> Me <my#email.com>
> email_draft.sender
=> nil
> email_draft.Sender
=> nil
> email_draft.reply_to
=> ["my#email.com"]
Is it possible that ActionMailer is throwing the error and still sending? Is this a known issue? The problem I have is that delayed_job keeps sending the email repeatedly.
UPDATE:
def EmailEngine < ActionMailer::Base
# Called with EmailEngine.delay.deliver_and_save(template)
def deliver_and_save(template)
# This appears to be raising the error
email_draft = EmailEngine.send(template) # this will invoke 'mail'
# Saved here to have a better record than the logs provide
Email.create(...
# Yet this still sends
email_draft.deliver
Found the problem!
delayed_job doesn't play super well with rails 3.1 and you have to use this new syntax:
EmailEngine.delay.deliver_and_save(template) # I was already doing this.
which it automatically tries to calls .deliver on the Mail::Message object that deliver_and_save returns. (So there's my problem: trying to call .deliver myself.)
SOLUTION: I rearranged my code and to call Email.create(.. somewhere outside of EmailEngine and then I called EmailEngine.delay.send(template) directly and completely removed deliver_and_save.
Woo!
Btw, any method invoked on a class that inherits from ActionMailer will return a Mail::Message object. ActionMailer does some black magic to make this happen (overwriting Ruby's method_missing so it can render views just like a controller, even though it behaves like a model in many ways).
This is about delayed_job and rails-3-mailer: https://github.com/collectiveidea/delayed_job#rails-3-mailers

exception handling in ruby on rails

I am a newbie to ruby on rails and developing some email apps, which uses AWS SES to send emails. I am uploading a csv file which contains only email address and an email will be sent to those email address.
Its a very basic app, which my app fails to send an email due to some reasons the app automatically stops sending emails. But I has to keep sending emails to the remaining email address.
How do I handle the exception. I have used ActionMailer.
Kindly Help me
def send_all_emails
#emails.each do |email|
send_one_mail email
end
end
def send_one_mail email
# your actual email sending code here
rescue
# this will log error to Rails log, but will not halt the whole app
Rails.logger.error $!
end
If you want to know about the exception,use
begin
#some code here
rescue =>ex
Rails.logger.error "#{ex.class.name} : #{ex.message}"
end
ps: You can also use rescue Exception =>ex .But don't use it until needed.Since it will catch all minor exceptions like 'NoMemoryError' which we don't want.Use the first one,it will catch only the Standard errors.

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